TypeScript generisk type ikke tildelbar som standard
Følgende kode:
function foo<T>(create: T & ((...args: any[]) => any) = () => { return { type: 'abc' }; })
{ ... }
Resultater med denne feilen:
Type
() => { type: string; }kan ikke tilordnes til typenT
Dette fungerer imidlertid fint:
function foo<T>(create: T & ((...args: any[]) => any)) { ... }
foo(() => { return { type: "ABC" }; });
I det siste tilfellet blir () => { type: string; } tildelt T
Hvorfor er det?
Det er på TypeScript nattlig bygg 1.9.0-dev.20160622
Svar #1
Det gir mening at det feiler når du setter standardverdien, men ikke når du kaller funksjonen med en verdi.
I funksjonsdefinisjonen er ikke T kjent, og derfor er også typen T & ((...args: any[]) => any) ukjent.
Snittyper:
En intersection type, Person & Serializable & Loggable, for eksempel, er en Person og Serializable og Loggable. Det betyr at et objekt av denne typen vil ha alle medlemmer av alle tre typene.
Men med ditt eksempel, hva betyr det for en T?
Når du faktisk kaller funksjonen og sender inn en verdi, kan kompilatoren prøve å finne ut hva dette T er, og dermed feiler det ikke og antar at T er () => { type: string; }.
Det samme vil skje med:
function fn<T>(a: T & string = "str") { // fails
return null;
}
fn2("str"); // doesn't fail
Men hvis du bruker unionstyper, vil det ikke feile:
function fn<T>(a: T | string = "str") {
return null;
}
Fordi "str" er en streng, og derfor er det T er, ikke relevant.
Rediger
Jeg er ikke helt sikker på hva du prøver å gjøre, men jeg har en følelse av at det å bruke snitt-typer ikke er det rette for deg.
Hvis jeg forstår deg, så er dette en bedre løsning:
type MyCallback = (...args: any[]) => any;
let defaultFn: MyCallback = () => { return { type: 'abc' }; };
function doSomething<T extends MyCallback>(fn: T = defaultFn as T) {
...
}
Du kan bruke et grensesnitt i stedet for typen:
interface MyCallback {
(...args: any[]): any;
}
(kode i lekeplass)
