How to Type Promises in TypeScript
Use typed promises in TypeScript when async code should guarantee the resolved value shape. This is essential for API calls, database queries, async helpers, and any workflow where the next step depends on reliable types.
What you’ll build or solve
You’ll learn how to type promises in TypeScript with Promise<T>, async functions, and reusable generic helpers. You’ll also know how promise typing improves autocomplete and safety.
Learn TypeScript on Mimo
When this approach works best
This approach is the right choice when async values need strong type guarantees.
Common real-world scenarios include:
- API fetch helpers
- Database queries
- Auth token loaders
- File reads
- Delayed utilities
This is a bad idea when synchronous values are being wrapped unnecessarily just to “look async.”
Prerequisites
You only need:
- Basic TypeScript types
- Familiarity with promises
- Understanding of async/await
Step-by-step instructions
Step 1: Use Promise<T> as the return type
The core syntax is:
function getUser(): Promise<string> {
return Promise.resolve("Alex");
}
This guarantees the resolved value is a string.
Use the same pattern for arrays and objects.
function getScores(): Promise<number[]> {
return Promise.resolve([95, 88, 76]);
}
Step 2: Type async functions the same way
Async functions should still use Promise<T>.
async function loadCount(): Promise<number> {
return 10;
}
Even though the returned value is 10, the real type becomes Promise<number>.
Step 3: Type object-based promise results
This is common for API helpers.
type User = {
id: number;
name: string;
};
function fetchUser(): Promise<User> {
return Promise.resolve({
id: 1,
name: "Alex"
});
}
This makes downstream code strongly typed.
Step 4: Use generic promise helpers
Reusable utilities often return generic promises.
function wrapInPromise<T>(value: T): Promise<T> {
return Promise.resolve(value);
}
This keeps async helpers flexible.
What to look for:
- Use
Promise<T>for resolved value typing - Async functions still return promises
- Great for APIs and reusable helpers
- Object promises improve downstream safety
- Generics keep helpers reusable
Examples you can copy
String result
Promise<string>
User object
Promise<User>
Generic helper
Promise<T>
Common mistakes and how to fix them
Mistake 1: Returning raw values in the type
What the reader might do:
async function load(): number
Why it breaks: async functions always return promises.
Corrected approach:
Use Promise<number>.
Mistake 2: Using any for promise results
What the reader might do:
Promise<any>
Why it breaks: downstream type safety disappears.
Corrected approach:
Define the exact resolved shape.
Mistake 3: Typing the promise object instead of the resolved value
What the reader might do:
Confuse Promise<Response> with parsed JSON data.
Why it breaks: later property access becomes wrong.
Corrected approach:
Type the final resolved data shape.
Troubleshooting
If async functions mismatch, wrap the return type in Promise<T>.
If autocomplete is weak, replace any.
If API parsing changes shape, update the resolved object type.
If helpers should stay generic, use Promise<T>.
Quick recap
- Use
Promise<T>for resolved value types - Async functions still return promises
- Prefer exact object shapes over
any - Use generics for reusable helpers
- Type the final resolved data
Join 40M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot