Eksporter returtype av funksjon i Typescript
Jeg har en funksjon som bygger et objekt, slik som dette:
function toast() {
return {
a: "a",
b: "b"
}
}
Jeg kan definere typen til funksjonen som
type ToastFunctionType = typeof toast
Denne typen ville være
() => { a: string; b: string; }
Jeg vil imidlertid bare ha typen til returverdien. Er det mulig å hente typen til returverdien av toast? I mitt brukstilfelle bruker de faktiske verdiene av objektene ganske verbose generiske typeargumenter. Typeinference får dem helt riktig, og jeg vil gjerne unngå å vedlikeholde et veldig verbose grensesnitt (som jeg må eksportere).
Det jeg vil ha når det gjelder toast, er bare
{ a: string; b: string; }
Svar #1
Ja, det er mulig. Trikset er å ha en verdi et sted som er deklarert med typen du trenger (returtypen til toast()), uten faktisk å kalle toast(). Du kan gjøre det ved å introdusere en annen funksjon som returnerer en verdi av passende type (den faktiske verdien er null), deretter opprette en variabel og tildele den verdien som returneres av den funksjonen, og deretter hente typeof av den.
Jeg kunne ikke finne en måte uten å legge til en ubrukt variabel, men siden variabelen er initialisert med null som umiddelbart returneres fra funksjonen, antar jeg at kjøretidsoverhead er ubetydelig. Her er koden:
function toast() {
return {
a: "a",
b: "b"
}
}
function getReturnType<R> (f: (...args: any[]) => R): {returnType: R} {
return null!;
}
// dummy variable, used for retrieving toast return type only
let toastType = getReturnType(toast);
export type ToastReturnType = typeof toastType.returnType;
OPPDATERING feb 2018
I den kommende 2.8-utgivelsen er det noen nye språkfunksjoner som gjør det mulig uten å involvere dummyvariabler og funksjoner.
Dette eksemplet kompilerer med typescript@next:
export function z() {
return {a: 1, b: '2'}
}
export function v() {
}
type ReturnType<T extends (...args: any[]) => any> =
T extends (...args: any[]) => infer R ? R : never;
export type RZ = ReturnType<typeof z>; // { a: number; b: string; }
export type RV = ReturnType<typeof v>; // void
TypeScript >= 2.8
Fra og med versjon 2.8 har TypeScript en innebygd generisk ReturnType som du kan bruke.
