Weboldal keresés

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 any legyen 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 new operátorral példányosítanak, annak típusparaméterei ugyanúgy kerülnek kikövetkeztetésre, mint egy függvényhívásnál.

Kapcsolódó cikkek