What is ReturnType?
In TypeScript, ReturnType<Type>
is a utility type that allows developers to extract the return type of a function or a callable object. This utility type is particularly useful in situtations where you want to capture and work wih the specific type that a function is expected to return, without having to annotate it.
type ReturnType<T extends (...args: any) => any> =>
T extends (...args: any) => infer R ? R : any
How does ReturnType work?
Example 1: return the type of a function returning a number
function getNumber(): number {
return 42;
}
type NumberReturnType = ReturnType<typeof getNumber>;
// NumberReturnType = number
Example 2: return the type of a function returning an object
function getObject(): { name: string; age: number; isMarried: boolean } {
return { name: "John", age: 30, isMarried: false };
}
type ObjectReturnType = ReturnType<typeof getObject>;
// ObjectReturnType = { name: string; age: number; isMarried: boolean }
Example 3: return the type of a function returning an array
function getArray(): number[] {
return [1, 2, 3, 4, 5];
}
type ArrayReturnType = ReturnType<typeof getArray>;
// ArrayReturnType = number[]
Recap
TypeScript’s type inference system automatically deduces types in various coding scenarios, allowing developers to write code with fewer explicit type annotations. However, there are cases where explicit type annotations prove beneficial:
- Function Return Types: Improves code clarity and documentation, necessary when TypeScript can’t infer accurately.
- Complex Object Structures: Ensures TypeScript understands intricate object structures in function parameters or return values.
- Variables with Ambiguous Types: Reduces confusion for variables with potentially multiple types.
- Interfaces and Custom Types: Vital for defining the shape and structure of custom types or interfaces.
Example 1: The function is designed to return a number, and in this particular instance, there is no need to explicitly specify the return type.
function getNumber() {
return 42;
}
type NumberReturnType = ReturnType<typeof getNumber>;
// NumberReturnType = number
Example 2: In certain scenarios, if you receive an array with numbers as input and intend to produce an array with strings as output, it becomes necessary to explicitly specify that the array will have a string type instead of numbers.
function getArray(...arr: number[]): string[] {
return [...arr].map(String);
}
type ArrayReturnType = ReturnType<typeof getArray>;
// ArrayReturnType = string[]
Example 3:
Consider a scenario where we have a function named fetchUsers
responsible for retrieving user data from an API. The API, in this case, returns data with complex type structures. It becomes essential to explicitly specify the expected object shape to TypeScript, ensuring accurate interpretation of the API response.
async function fetchUsers(): Promise<
Array<{
name: string;
isMarried: boolean;
address: { street: string };
}>
> {
const response = await fetch("https://api.example.com/user");
const data = await response.json();
return data;
}
type UserReturnType = ReturnType<typeof fetchUsers>;
// UserReturnType = Promise<{
// name: string;
// isMarried: boolean;
// address: { street: string };
// }[]>
Resources
Thank you!
Thank you for your time and for reading this!