Syntax
ReturnType<typeof fn>
Parameters<typeof fn>Examples
ReturnType<T>
Extracting a function's return type without redefining it manually.
function createUser(name: string, age: number) {
return { id: Date.now(), name, age, createdAt: new Date() };
}
type User = ReturnType<typeof createUser>;
// User is inferred as: { id: number; name: string; age: number; createdAt: Date }
// No need to manually write out this shape - it stays in sync with the function automaticallyParameters<T>
Extracting a function's parameter types as a tuple.
function greet(name: string, greeting: string = "Hello") {
return `${greeting}, ${name}!`;
}
type GreetParams = Parameters<typeof greet>;
// GreetParams is: [name: string, greeting?: string]
function logCall(...args: Parameters<typeof greet>) {
console.log("Calling greet with:", args);
}Best practices
- Use ReturnType<typeof fn> to derive a type from a function's actual implementation, rather than manually duplicating and maintaining a matching interface
- Always use typeof when passing a function to these utilities (ReturnType<typeof myFunc>), since they operate on types, not runtime values
- Use Parameters<T> when writing a wrapper or decorator function that needs to accept the exact same arguments as another function
- These are especially valuable for third-party library functions whose exact return shape you do not want to manually re-type and keep in sync
At a glance
- Purpose
- Static types for JavaScript
- File extension
- .ts ยท .tsx
- Runs in
- Compiled to JavaScript
- Usually used with
- JavaScript and its ecosystem
Specifications & further reading
Related TypeScript documentation
Partial<T> and Required<T>
Partial<T> constructs a new type with every property of T marked optional - useful for representing partial updates, like a PATCH request body. Required<T> does the opposite, making every property mandatory even if the original type had optional ones, useful for ensuring a fully-populated object at a specific point in your code.Pick<T> and Omit<T>
Pick<T, Keys> constructs a new type by selecting only the specified properties from T. Omit<T, Keys> does the reverse, constructing a new type with all properties of T except the specified ones. Both are extremely common for deriving smaller, focused types from a larger base type without duplicating the definition.Record<K, V>
Record<Keys, ValueType> constructs an object type with a specific set of keys, all mapped to the same value type. It is the concise, standard way to type dictionary-like objects, and is often clearer than writing an equivalent index signature by hand.Readonly<T>
Readonly<T> constructs a new type where every property of T is marked readonly, preventing reassignment after the object is created. It is a shallow transformation - nested objects within a Readonly<T> are not automatically deep-frozen, only the top-level properties are protected from reassignment.
Partial<T> constructs a new type with every property of T marked optional - useful for representing partial updates, like a PATCH request body. Required<T> does the opposite, making every property mandatory even if the original type had optional ones, useful for ensuring a fully-populated object at a specific point in your code.Pick<T> and Omit<T>
Pick<T, Keys> constructs a new type by selecting only the specified properties from T. Omit<T, Keys> does the reverse, constructing a new type with all properties of T except the specified ones. Both are extremely common for deriving smaller, focused types from a larger base type without duplicating the definition.Record<K, V>
Record<Keys, ValueType> constructs an object type with a specific set of keys, all mapped to the same value type. It is the concise, standard way to type dictionary-like objects, and is often clearer than writing an equivalent index signature by hand.Readonly<T>
Readonly<T> constructs a new type where every property of T is marked readonly, preventing reassignment after the object is created. It is a shallow transformation - nested objects within a Readonly<T> are not automatically deep-frozen, only the top-level properties are protected from reassignment.