javascript - Bevara typsignaturen när en funktion som lämnats som parameter returneras
Jag har en funktion som kallas conditional som tar emot ett booleskt värde och en funktion, och returnerar den funktionen om det booleska värdet är sant, annars returnerar den en dummyfunktion.
function conditional(x, f) {
if(x)
return f
else
return () => {}
}
Så, jag kan köra kod på det här sättet:
let mySqrt = conditional(true, Math.sqrt)
let add = (x, y) => x + y
let myAdd = conditional(true, add)
Men när jag lägger till typer till den villkorliga funktionen, går typdefinitionen för funktionen som skickas till conditional-funktionen förlorad. Och detta gör det möjligt att skriva kod som mySqrt("a") utan att TypeScript klagar.
Hur lägger jag till typer till den villkorliga funktionen så att typen på den resulterande funktionen bevaras?
Svar #1
Du behöver använda en generisk typparameter för att representera typen av funktionen:
function conditional<T extends (...args: any[]) => any>(x: boolean, f: T): T {
if (x)
return f;
else
return (() => { }) as any; // we need an assertion here to make the empty function compatible with T
}
// Usage
let mySqrt = conditional(true, Math.sqrt); //mySqrt will be of type (x: number) => number
let add = (x: number, y: number) => x + y;
let myAdd = conditional(true, add); // myAdd will be of type (x: number, y: number) => number
Svar #2
Du kan använda en kombination av generiska typer och metodöverlagringssignaturer.
function conditional<T extends Function>(x: true, f: T): T;
function conditional<T extends Function>(x: false, f: T): () => {};
function conditional<T extends Function>(x: boolean, f: T) {
if(x)
return f
else
return () => {}
}
let mySqrt = conditional(true, Math.sqrt)
mySqrt('a') // error
När man tillhandahåller överlagrade metodsignaturer kommer kompilatorn att dölja den faktiska, mer flexibla implementeringen.
