Implement ReturnType<T> Utility Type from Scratch in TypeScript
2 min read

Hey there, TypeScript tinkerers! đź‘‹
Ever thought about how doesReturnType<T>
works under the hood? Today we’re going to build our own version of ReturnType<T>
from the ground up, so you can see how it works under the hood. Let’s dive in!
Why do I need to extract a Function’s Return Type?
Imagine you are importing a function from an external library that did not export its return type.
You can easily grab its return type using ReturnType<T>
util and use it anywhere you want -
import {fetchUser} from 'some-external-library';
export type User = ReturnType<typeof fetchUser>;
Before implementing this, let’s first understand the infer
keyword.
Meet infer
: TypeScript’s “Guess What This Is” Keyword
Think of infer
like guessing someone’s coffee order based on the smell—TypeScript smells inside a type, grabs the bit you care about, and stores it in a new type variable.
The classic pattern looks like this:
type Foo = T extends /* something */ ? /* use infer here */ : never;
When T
matches the pattern, the compiler “infers” the piece you asked for.
Building MyReturnType<T>
Step-by-Step
Let’s write our own version, MyReturnType<T>
:
type MyReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
Breakdown
T extends (...args: any[]) => infer R
We ask: “Hey TypeScript, isT
a function type?”
We promise: “If yes, you may infer its return type and call itR
.”? R : never
If the condition is true, yield that inferredR
; otherwise, default tonever
.
That’s it — just four lines!
Putting MyReturnType<T>
to Work
function makeSmoothie(flavor: "mango" | "berry") {
return flavor === "mango"
? { flavor, calories: 250, fresh: true }
: { flavor, calories: 200, fresh: true };
}
type Smoothie = MyReturnType<typeof makeSmoothie>;
// { flavor: "mango" | "berry"; calories: number; fresh: boolean }
Conclusion
Knowing how to implement your own ReturnType<T>
isn’t just a neat party trick—it deepens your understanding of conditional types and paves the way to craft bespoke type utilities for your codebase.