typescript - Videreføre typeparametere til generisk type når man implementerer generisk funksjon
Si at jeg får en funksjonstype som dette. Jeg kan allerede implementere en funksjon av den typen, og trenger ikke å erklære argument- eller returtypene igjen:
type MyFunc = (args: string) => boolean;
// TS knows args is a string and return is boolean 👍
const myFunc: MyFunc = (args) => true;
Men, si at jeg får en generell funksjonstype. Jeg vil implementere en funksjon som følger denne typen, men videreføre de generiske typeparameterne til anroperen. Er dette mulig? Forsøket mitt gir en feil:
type ReturnsSomething<A> = (args: A) => A;
// Generic type 'ReturnsSomething' requires 1 type argument(s).ts(2314)
const logAndReturnSomething: ReturnsSomething = (args) => {
console.log(args);
return args;
};
logAndReturnSomething<string>('asdf');
Dette fungerer heller ikke:
type ReturnsSomething<A> = (args: A) => A;
// Cannot find name 'A'.ts(2304)
const logAndReturnSomething: ReturnsSomething<A> = (args) => {
console.log(args);
return args;
};
logAndReturnSomething<string>('asdf');
I mer kompliserte tilfeller vil jeg ikke omdefinere argumentene og returtypene i alle mine implementasjoner, da det ødelegger hensikten med en delbar ReturnsSomething generisk. Finnes det en måte å implementere en generisk funksjon som videresender sine typeargumenter til en generisk type?
Jeg kunne lage en wrapper-funksjon for å håndheve denne typen, men det betyr at jeg trenger et dobbelt funksjonskall hver gang jeg bruker den, jeg skulle ønske det var en renere måte:
type ReturnsSomething<A> = (args: A) => A;
function makeLogAndReturnSomething<A>(): ReturnsSomething<A> {
return (args) => {
console.log(args);
return args;
};
}
makeLogAndReturnSomething<string>()('asdf');
Jeg bruker TypeScript 4.6 for det det er verdt, ikke sikker på om 4.7 vil løse dette eller om det er en TS-syntaks jeg går glipp av.
Svar #1
Prøv dette:
type GenericFn = <A>(args: A) => A;
const logAndReturnSomething: GenericFn = (args) => {
console.log(args);
return args;
};
const result = logAndReturnSomething('asdf'); //infers return type as string
I hovedsak lager vi ikke en generisk type, men snarere en generisk funksjon. Det er forvirrende, jeg vet :)
Det finnes en flott kort YouTube-video hvis du vil fordype deg mer.
TS-lekeplass
