typescript - Típusbecslés ismeretlen típusról ismert típusra változik egy metódus használata után
Van egy osztályom egyetlen generikussal T, ahol néha értékkel lehet létrehozni, így a T ismert, néha érték nélkül, és így a T ismeretlen. Fárasztó megadni a típust, amikor nincs érték, és a típus esetleg ki lehetne következtetni.
Ez levezethető pontosan arra a problémára, amivel egy bonyolultabb osztálynál küzdök, ahol szükség van arra, hogy a T ne legyen ismeretlen, miközben egy érték nincs tárolva, mert később tárolható.
class Foo<T> {
value:T;
constructor(value?:T) {
if(value != null && value != undefined) {
this.value = value;
}
}
public set(value:T) {
this.value = value;
}
}
const fn1 = ():Foo<number> => {
const foo = new Foo(0); //foo is Foo<number>
foo.set(1);
return foo; //No error
}
const fn2 = ():Foo<number> => {
const foo = new Foo(); //foo is Foo<unknown>
foo.set(1);
//unknown accepts number apparently and such there is no type collision
//However, I want foo to be re-evaluated to be Foo<number>
return foo; //Error
//const foo: Foo<unknown>
//Type 'Foo<unknown>' is not assignable to type 'Foo<number>'.
// Type 'unknown' is not assignable to type 'number'.
}
const fn3 = ():Foo<number> => new Foo(); //No error, is inferred as being Foo<number>
Van valami, amit kihagytam, hogy lehetővé tegyem, hogy a generikus típus újraértékelődjön és ne legyen ismeretlen?
Alternatívaként, van-e mód arra, hogy soha ne legyen ismeretlen? Olyan módon, hogy ha azt csinálom, new Foo(), akkor típus megadását kérné. (Az is igaz, hogy ez nem a legjobb megoldás a feladatra, de a Foo<any> átalakítható Foo<number>-ré, szóval van-e mód arra, hogy az any legyen az alapértelmezett?)
Tudatában vagyok annak, hogy a megoldás egyszerűen az lenne, ha new Foo<number>()-t használnánk, azonban ez valami olyasminek tűnik, amit a TypeScriptnek képesnek kellene lennie kikövetkeztetni, és nem kellene megadni, ami plusz munkát jelenthet, ami esetleg nem szükséges.
Válasz #1
Van mód arra, hogy úgy állítsam be, hogy a
anylegyen az alapértelmezett?
Igen, egyszerűen használj egy alapértelmezett típust a generikusodhoz:
class Foo<T = any> {}
Játszótér hivatkozás
Válasz #2
Van valami, amit kihagytam, hogy lehetővé tegyem, hogy a generikus típus újraértékelődjön és ne legyen
ismeretlen?
Sajnos nem, a TypeScript soha nem értékeli újra. Egy osztály példány generikus típusának meghatározása csak az inicializáláskor történik:
Amikor egy generikus osztályt a
newoperátorral példányosítanak, annak típusparaméterei ugyanúgy kerülnek kikövetkeztetésre, mint egy függvényhívásnál.
