ReturnType<T> gives the return type of a function type, and Parameters<T> gives its parameter types as a tuple. Apply them to a function value with typeof, so the types follow the function whenever it changes:
User is never written out. Add a field to the object createUser returns and User has it too. This is the main use of these types: naming a type that already exists implicitly, often in code you do not own.
ReturnType Needs typeof
ReturnType takes a type, and a function name is a value. Passing the name directly is a compile error:
index.ts(6,24): error TS2749: 'createUser' refers to a value, but is being used as a type here. Did you mean 'typeof createUser'?
The fix is the one the message suggests: ReturnType<typeof createUser>. typeof in a type position asks for the type of a variable or function; see typeof for both meanings of that keyword.
ReturnType also works on a function type directly, without typeof: ReturnType<() => string> is string, and ReturnType<Handler> works when Handler is a function type alias.
Awaited and Async Functions
An async function returns a promise, so ReturnType gives Promise<...>. Awaited<T> unwraps it, the same way await does at runtime:
Awaited<T> leaves a non-promise type unchanged (Awaited<string> is string), so it is safe to apply when you are not sure whether a function is async. The standard library's type for Promise.all uses it for the same reason.
Parameters
Parameters<T> returns the parameter list as a labeled tuple, including optional and rest parameters. Index into it for a single parameter's type. It is useful for wrapping a function without repeating its signature:
Parameters<typeof fn>[2] includes undefined because the parameter is optional. Wrap it in NonNullable to get the object type alone.
ConstructorParameters and InstanceType
The class counterparts: ConstructorParameters<typeof C> is the constructor's parameter tuple, and InstanceType<typeof C> is the type of the object new C(...) returns. For a class you can name directly, the instance type is just C; InstanceType is for generic code that receives a class as a value:
build(Point, 3, "4") would be a compile error, because the rest parameter is typed from Point's own constructor. The as InstanceType<C> cast is needed because TypeScript cannot prove that new ctor(...) produces exactly InstanceType<C> for a generic C.
Overloads and Generic Functions
Two cases where the result may not be what you expect:
For overloads, ReturnType and Parameters look only at the last signature, so put the most general overload last or name the types explicitly. For generic functions, a type parameter with no argument becomes its constraint (unknown here); typeof identity<number> fixes it to one instantiation.
How ReturnType Is Built
All of these are conditional types with infer, defined in the standard library. Simplified:
type ReturnType<T extends (...args: any) => any> =
T extends (...args: any) => infer R ? R : any;
type Parameters<T extends (...args: any) => any> =
T extends (...args: infer P) => any ? P : never;
type InstanceType<T extends abstract new (...args: any) => any> =
T extends abstract new (...args: any) => infer R ? R : any;
infer R declares a type variable that TypeScript fills in by matching T against the pattern. The constraint on T is why ReturnType<string> is an error: string is not a function type. You can write your own extractors the same way, for example the element type of an array or the type a promise resolves to; the conditional types page shows how.
| Utility type | Input | Result |
|---|---|---|
ReturnType<F> | function type | return type |
Parameters<F> | function type | parameter tuple |
ConstructorParameters<C> | class (constructor) type | constructor parameter tuple |
InstanceType<C> | class (constructor) type | instance type |
Awaited<T> | any type | the value a promise resolves to, recursively |
ThisParameterType<F> | function type | the type of its this parameter |
OmitThisParameter<F> | function type | the same function without this |
Frequently Asked Questions
How do I get the return type of a function in TypeScript?
Use ReturnType<typeof fn>. typeof fn turns the function value into its type, and ReturnType extracts what it returns. Writing ReturnType<fn> without typeof is error TS2749, because fn is a value, not a type.
How do I get the return type of an async function?
ReturnType<typeof fn> gives the promise, for example Promise<User>. Wrap it in Awaited to get the resolved value: Awaited<ReturnType<typeof fn>> is User. Awaited also unwraps nested promises.
What does Parameters do in TypeScript?
Parameters<typeof fn> returns a tuple of the function's parameter types, with their names as labels: for (name: string, age?: number) it is [name: string, age?: number]. Index it to get one parameter's type, like Parameters<typeof fn>[0].
What is the difference between InstanceType and ConstructorParameters?
Both take a class type (typeof MyClass). InstanceType gives the type of the object that new creates, and ConstructorParameters gives the constructor's parameters as a tuple. They are the class counterparts of ReturnType and Parameters.
What does ReturnType return for an overloaded function?
The return type of the last overload signature only. For a function with (x: string): string followed by (x: number): number, ReturnType is number. The same applies to Parameters. There is no built-in way to get all overloads.