TypeScript: zpřístupnit metodu generického rozhraní A<T> pouze tehdy, pokud je T určitého typu
Podívejte se prosím na tento kód:
interface A<T> {
method1(): A<T>;
}
interface B<T extends Function> extends A<T> {
method2(): B<T>;
}
var foo: A<Function>;
foo.method1();
foo.method2();
Očekával jsem, že foo bude kompatibilní s typem B<Function>, ale místo toho dostanu error TS2339: Property 'method2' does not exist on type 'A<Function>'. Můžu nějak přepsat rozhraní B, aby to fungovalo?
Vlastně se snažím opravit typování pro _.memoize v lodashu:
// This should be OK. The type of result1 should be compatible with aFunction.
var result1 = _(aFunction).memoize().value();
// And this should be an error.
var result2 = _(aNonFunctionValue).memoize().value();
AKTUALIZACE. V zásadě je moje otázka: mohu napsat takovou generickou metodu pro A<T>, která bude dostupná pouze tehdy, pokud T je podtypem nějakého jiného typu U?
Odpověď č. 1
Mohu nějak přepsat rozhraní B, aby to fungovalo?
Řešení
Zde je kód:
interface A<T> {
method1(): A<T>;
}
interface B<T extends Function> extends A<T> {
method2(): B<T>;
}
interface A<T> {
method2<T extends Function>(): B<T>;
}
var foo: A<Function>;
foo.method1();
foo.method2(); // works!
Dosažení řešení
Pojďme se na chvíli zastavit a zamyslet se, co chceme dělat:
var foo: A<Function>;
foo.method2(); // Should work
To znamená, že A<Function> by na něm měl mít method2. Takže:
interface A<T> {
method2<T extends Function>(): B<T>;
}
A tato metoda dva přidává generické omezení na T a vrací něco typu B.
Zbytek je jasný v konečném řešení 🌹
Odpověď č. 2
Ukazuje se, že TypeScript to nepodporuje. Viz https://github.com/Microsoft/TypeScript/issues/1290
AKTUALIZACE 2019: Teď, když máme podmíněné typy, je to hračka:
interface A<T> {
method1(): A<T>;
method2: T extends Function ? () => A<T> : never;
}
declare var foo: A<Function>;
foo.method1();
foo.method2();
