typescript - TS hjälpverktygstypinformation förlorad med "typeof" operatorn
Jag hittade nyligen vad som ser ut som en situation där TS typeof-operatorn förlorar viktig typinformation. Jag misstänker att det i själva verket handlar om ett missförstånd från min sida, men lyckligtvis är det lätt att illustrera:
const omit = <T extends object, K extends keyof T>(dict: T, key: K) => {
return dict as Omit<T, K>;
};
// implicit object
const obj = { foo: 1, bar: 2 };
// full type info available after "omit"
const obj2 = omit(obj, "bar");
// type info is "lossy"
type O2 = typeof obj2;
I vs-code när jag hovrar över obj2 uttrycks dess typ som: Omit<{foo: number, bar: number}, "bar">. Detta är både vad jag förväntade mig och ville ha. Men när jag hovrar över typen O2 får jag en typ av { foo: number }.
Du kan se hur dessa två typer är lika men den första innehåller mer typinformation eftersom den har bevarat objektets övergripande form tillsammans med utelämnandet från den formen.
Detta gäller också i den något mer explicita situationen där den ursprungliga objektets typ anges:
// explicit object
type Start = { foo: number, bar: number};
const obj3: Start = {foo: 1, bar: 2};
// full type info available on obj4
const obj4 = omit(obj3, "bar");
// again "reduced" to just the remaining props
type O4 = typeof obj4;
Finns det något sätt på vilket den fullständiga typinformationen kan fångas av en nedströms typpdefinition som O2 eller O4? Jag förstår att i många fall är detta reducerade tillstånd faktiskt att föredra eftersom det både är enklare och korrekt, vilket gör det lättare att förstå, men i mer komplexa miljöer är det användbart att bevara denna saknade information.
Typescript-lekplats
Jag har märkt att om jag skapar en identitetsfunktion och tilldelar en annan variabel genom identitetsfunktionen bevaras typinformationen. Detta är användbart men svarar inte helt på min fråga.
Exempel :
const omit = <T extends object, K extends keyof T>(dict: T, key: K) => {
return dict as Omit<T, K>;
};
function identity<T>(thing: T):T {
return thing;
}
// implicit object
const obj = { foo: 1, bar: 2 };
// full type info available after "omit"
const obj2 = omit(obj, "bar");
const myObj = identity(obj2);
type O2 = typeof myObj;
typningen för både
obj2ochmyObjär densamma och komplett;O2är fortfarande förlustfull.