Obtaining the return type of a function
Use built-in ReturnType
:
type SomeType = ReturnType<typeof SomeFunc>
ReturnType
expands to:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
The code below works without executing the function. It's from the react-redux-typescript library (https://github.com/alexzywiak/react-redux-typescript/blob/master/utils/redux/typeUtils.ts)
interface Func<T> {
([...args]: any, args2?: any): T;
}
export function returnType<T>(func: Func<T>) {
return {} as T;
}
function mapDispatchToProps(dispatch: RootDispatch, props:OwnProps) {
return {
onFinished() {
dispatch(action(props.id));
}
}
}
const dispatchGeneric = returnType(mapDispatchToProps);
type DispatchProps = typeof dispatchGeneric;
EDIT
As of TypeScript 2.8 this is officially possible with ReturnType<T>
.
type T10 = ReturnType<() => string>; // string
type T11 = ReturnType<(s: string) => void>; // void
type T12 = ReturnType<(<T>() => T)>; // {}
type T13 = ReturnType<(<T extends U, U extends number[]>() => T)>; // number[]
See this pull request to Microsoft/TypeScript for details.
TypeScript is awesome!
Old-school hack
Ryan's answer doesn't work anymore, unfortunately. But I have modified it with a hack which I am unreasonably happy about. Behold:
const fnReturnType = (false as true) && fn();
It works by casting false
to the literal value of true
, so that the type system thinks the return value is the type of the function, but when you actually run the code, it short circuits on false
.
The easiest way in the TypeScript 2.8:
const foo = (): FooReturnType => {
}
type returnType = ReturnType<typeof foo>;
// returnType = FooReturnType