Menu

TypeScript ReturnType, Parameters and Awaited Utility Types

ReturnType, Parameters, ConstructorParameters, InstanceType and Awaited extract types from functions, classes and promises. Learn how to use them with typeof, how to get the result type of an async function, what happens with overloads and generics, and how ReturnType is built with infer.

This page includes runnable editors - edit, run, and see output instantly.

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 typeInputResult
ReturnType<F>function typereturn type
Parameters<F>function typeparameter tuple
ConstructorParameters<C>class (constructor) typeconstructor parameter tuple
InstanceType<C>class (constructor) typeinstance type
Awaited<T>any typethe value a promise resolves to, recursively
ThisParameterType<F>function typethe type of its this parameter
OmitThisParameter<F>function typethe 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.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED