What do ReturnType and Parameters do? How would you implement them?
Take a moment.
Say your answer out loud or write it down first — retrieval is what makes it stick. Reveal when you're ready.
Short answer
ReturnType<T> extracts a function's return type; Parameters<T> extracts its argument list as a tuple. Both use conditional types with infer: T extends (...args: infer A) => infer R.
Detailed explanation
Conditional types ask structural questions at the type level: T extends SomeShape ? X : Y. The infer keyword declares a placeholder to be solved during matching. ReturnType's definition is type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never — match T against a function pattern, capture R. Parameters similarly captures args as a tuple: infer A in the argument position yields [string, number] style tuples, perfect for building wrapper functions that forward arguments: function logged<F extends AnyFn>(fn: F, ...args: Parameters<F>): ReturnType<F>. Related family members: Awaited<T> unwraps promises recursively, InstanceType<T> gets constructor instance types, ThisParameterType handles this-typing. These shine when you can't modify source code — third-party functions, generated clients — letting you derive types instead of hand-writing duplicates that drift.
Example
function createSession(userId: string, ttlDays = 7) {
return { token: crypto.randomUUID(), expiresAt: Date.now() + ttlDays * 864e5 };
}
type Session = ReturnType<typeof createSession>;
type SessionArgs = Parameters<typeof createSession>; // [userId: string, ttlDays?: number]
function timed<A extends unknown[], R>(fn: (...args: A) => R): (...args: A) => R {
return (...args) => {
console.time('call');
try { return fn(...args); } finally { console.timeEnd('call'); }
};
}Interview tip
Write the conditional type with infer yourself rather than quoting docs — implementing ReturnType from scratch is a classic senior-level whiteboard moment.
Common mistakes
- Not knowing
inferor where it may appear. - Forgetting the constraint (...args: any) => any required on these utilities.