Skip to main content

Utility type returntype in TypeScript

ReturnType is a TypeScript utility type that pulls the return type out of a function type automatically.

Theory

TL;DR

  • Think of it as a receipt for a function: it tells you what comes out, without hardcoding it.
  • Works on callable types only. Pass a function type T, get back R where T is (...args: any[]) => R.
  • If the function changes its return type, every type built with ReturnType updates too.
  • For async functions, ReturnType gives Promise<T>. Use Awaited<ReturnType<...>> to unwrap it.
  • On overloaded functions, TypeScript picks the last overload's return type, not the one matching your call.

Quick example

ts
function createUser(name: string, age: number) { return { name, age, createdAt: new Date() }; } // No need to manually write { name: string; age: number; createdAt: Date } type User = ReturnType<typeof createUser>; // { name: string; age: number; createdAt: Date } // User stays in sync if createUser changes its return shape function processUser(user: User) { console.log(user.name, user.createdAt); }

typeof createUser gives TypeScript the full function type. ReturnType then strips the parameters and keeps only the output.

Key difference

ReturnType extracts only the output type of a function. typeof gives you the whole function signature, including parameters. Parameters<T> does the opposite and extracts the input tuple. ReturnType ignores inputs completely and focuses on what a function delivers.

When to use

  • A function's output feeds another function as a parameter: use ReturnType<typeof producer> to type that parameter.
  • State type in a React component should match an API fetcher's output: ReturnType<typeof fetchUser> instead of a separate interface.
  • You want a type alias for a function's output that updates when the function changes.
  • Skip it for simple primitives. If a function returns string, just write string.

How the compiler handles this

TypeScript resolves ReturnType<T> using conditional types from TS 2.8. Internally it is defined as T extends (...args: any) => infer R ? R : any. The compiler pattern-matches T against a function signature and captures R from the return position. No runtime cost at all - types are fully erased in JavaScript output.

Common mistakes

Using it on a non-function type:

ts
type Bad = ReturnType<{ name: string }>; // Error: Type '{ name: string }' does not satisfy the constraint '(...args: any) => any'

Fix: use typeof obj.method for object methods.

Forgetting async wraps everything in Promise:

ts
async function fetchData() { return { id: 1, name: "Alice" }; } type Wrong = ReturnType<typeof fetchData>; // Promise<{ id: number; name: string }> type Right = Awaited<ReturnType<typeof fetchData>>; // { id: number; name: string }

Awaited<T> was added in TypeScript 4.5.

Overloaded functions always resolve to the last overload:

ts
function parse(input: string): string; function parse(input: number): number; function parse(input: any): any { return input; } type Result = ReturnType<typeof parse>; // number, not string or a union

TypeScript resolves to the last declared overload, not the one you would actually call. This trips up a lot of developers.

Void is a valid ReturnType result:

ts
const log = () => { console.log("hi"); }; type LogReturn = ReturnType<typeof log>; // void const val: LogReturn = 123; // Error

void here means "don't use the return value," not "no type."

Real-world usage

In most codebases, ReturnType shows up most at the API boundary, where fetcher functions hand their results to state or UI components.

  • React Query / TanStack Query: type QueryData = ReturnType<typeof api.fetchPost> to type useQuery data.
  • Zod: type Schema = ReturnType<typeof schema.parse> for the validated output type.
  • Express middleware: type HandlerReturn = ReturnType<typeof authMiddleware> when chaining handlers.

Follow-up questions

Q: What does ReturnType return for an async function?
A: It returns Promise<T>, not T directly. Chain it with Awaited<ReturnType<typeof fn>> to get the unwrapped type.

Q: How does ReturnType handle overloaded functions?
A: It picks the return type of the last overload, regardless of which overload you would actually call. This is a known TypeScript behavior, not a bug.

Q: What is the difference between ReturnType and Parameters?
A: ReturnType extracts the output type. Parameters extracts the input types as a tuple. They are complementary.

Q: Can you implement ReturnType yourself?
A: Yes: type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : any;. The infer R keyword tells TypeScript to capture whatever sits in the return position into R.

Q: Does it work on class methods?
A: Yes. Use ReturnType<typeof instance.method> or ReturnType<ClassName['methodName']>.

Examples

Basic: syncing a state type with a fetcher

ts
async function fetchUser(id: string) { const res = await fetch(`/api/users/${id}`); return res.json() as { id: string; name: string; email: string }; } // Tracks fetchUser's output automatically type UserState = Awaited<ReturnType<typeof fetchUser>>; // { id: string; name: string; email: string } // Add 'role: string' to fetchUser's return - UserState picks it up with no extra work

Writing the type manually as { id: string; name: string; email: string } means updating two places when fetchUser changes. With ReturnType, the type lives in one place.

Intermediate: a function that consumes another function's output

ts
function buildReport(name: string, score: number) { return { title: `Report for ${name}`, score, passed: score >= 60, generatedAt: new Date(), }; } // processReport is always compatible with buildReport's output shape function processReport(report: ReturnType<typeof buildReport>) { if (report.passed) { console.log(`${report.title} - score: ${report.score}`); } } processReport(buildReport("Alice", 85)); // OK

This pattern is common in data processing layers where one function hands off to another. Change buildReport, and TypeScript flags any mismatch in processReport at compile time.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.

Finished reading?