tezvyn:

How do you type an async function return in TypeScript?

AI-drafted, machine-checkedSource: developer.mozilla.orgintermediate
How do you type an async function return in TypeScript?

This tests if you know async functions always return Promise<T>. A great answer: annotate Promise<User>, return User from the body, and note TypeScript implicitly wraps it. A red flag is omitting Promise and typing the return as just User.

WHAT THIS TESTS: Whether you understand that the async keyword changes both the runtime behavior and the static type of a function. Specifically, it checks if you know that an async function's return type annotation must explicitly include the Promise generic, even though the value you return inside the function body is not itself a Promise. Interviewers want to see that you grasp the distinction between what you write in the return statement and what the caller actually receives.

A GOOD ANSWER COVERS: First, the correct signature is async function fetchUser(id: string): Promise<User>. Second, inside the function you can simply return user where user has type User, and the TypeScript compiler will implicitly treat the function as returning Promise<User>. Third, if you try to annotate the return type as just User, TypeScript will report an error because the async keyword guarantees a Promise is returned at runtime. Fourth, if the function body has no return statement, the resolved value is undefined so the type becomes Promise<void>. Fifth, if you throw an error or reject, the Promise rejects and the caller should handle that with try catch or .catch.

COMMON WRONG ANSWERS: Annotating the return type as User instead of Promise<User>. Manually returning Promise.resolve(user) inside an async function to satisfy the type checker, which is redundant because async already does this wrapping. Claiming that TypeScript strips the Promise wrapper or that await inside the function changes the outer return type. Also, saying you can return Promise<User> from inside the body and that it unwraps automatically; while returning a Promise inside an async function is legal, it results in a double wrapped Promise<Promise<User>> at the type level unless flattened by the type system, though at runtime JavaScript flattens it.

LIKELY FOLLOW-UPS: How does error handling affect the return type? The answer is that thrown errors become rejected Promises, so the return type alone does not capture failure; you might discuss Promise<User> versus a Result type. What happens if you return a Promise inside an async function? The answer is that it gets flattened at runtime but TypeScript may infer a nested Promise type unless you await it first. How would you type a function that sometimes returns null? You would write Promise<User | null>.

ONE CONCRETE EXAMPLE: Consider async function fetchUser(id: string): Promise<User> { const res = await fetch(/api/users/${id}); const data = await res.json(); return data as User; }. The return statement hands back a User object, but the caller receives Promise<User>. If you wrote return await fetch(...) without parsing, the type would be Promise<Response>. If you accidentally annotated the function as User and wrote return data, TypeScript would error with Type User is not assignable to type Promise<User>.

Source: developer.mozilla.org

Read the original → developer.mozilla.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.