How to fix The return type of an async function or method must be the global Promise<T> type in TypeScript
This error occurs when you annotate an async function with a non-Promise return type. Async functions always return a Promise, so TypeScript requires you to wrap the return type in Promise<T>.
Quick fix
Fixes TS1058
async function getUsername(): string { // ❌ Error: TS1058
const user = await fetchUser();
return user.name;
}- Identify the async function with incorrect type annotation
- Wrap the return type in Promise<T>
- Handle functions that don't return a value
- Use union types for complex return values
async function getUsername(): string { // ❌ Error: TS1058const user = await fetchUser();return user.name;}The return type of an async function or method must be the global Promise<T> type
What this error means
In TypeScript, when you declare a function with the `async` keyword, the function is guaranteed to return a Promise, even if you don't explicitly return one. The `await` keyword inside async functions only works with Promises. When you specify a return type annotation for an async function, TypeScript requires that type to be `Promise<T>` where `T` is the type of the value being resolved. If you try to annotate an async function with a non-Promise type (like `string`, `number`, or a custom object), TypeScript will raise error TS1058. This is a fundamental requirement in TypeScript's type system—it ensures type safety when working with asynchronous code.
Typical symptoms
- Compilation error appears when declaring an async function with a simple return type
- Error message mentions 'The return type of an async function or method must be the global Promise<T> type'
- IDE shows red squiggly line under the return type annotation
- Happens even if the function body correctly returns the expected value
- Issue affects both named async functions and arrow functions
Common causes
- Annotating an async function return type without wrapping it in Promise<> (most common)
- Copy-pasting code from a synchronous function and adding async without updating the return type
- Misunderstanding that async functions always return Promises, regardless of what you return inside them
- Using an incorrect Promise type like Promise[] instead of Promise<T>
- Trying to return a thenable object that doesn't fully conform to Promise spec
How to fix "The return type of an async function or method must be the global Promise<T> type"
Look for the function causing the error. It will look something like this:
async function getUsername(): string { // ❌ Error: TS1058
const user = await fetchUser();
return user.name;
}The issue is that the return type is annotated as string, but async functions must return Promise<string>.
Change the return type annotation to Promise<T> where T is your original type:
// ✅ Correct - Named function
async function getUsername(): Promise<string> {
const user = await fetchUser();
return user.name;
}
// ✅ Correct - Arrow function
const getUsername = async (): Promise<string> => {
const user = await fetchUser();
return user.name;
};
// ✅ Correct - Class method
class UserService {
async getUsername(): Promise<string> {
const user = await fetchUser();
return user.name;
}
}The function body doesn't change—only the type annotation.
If your async function doesn't return a value, use Promise<void>:
// ❌ Error
async function logUser(): undefined {
const user = await fetchUser();
console.log(user.name);
}
// ✅ Correct
async function logUser(): Promise<void> {
const user = await fetchUser();
console.log(user.name);
}If your async function can return different types, use a union type inside Promise:
// ✅ Return a union
async function fetchData(): Promise<string | null> {
try {
return await api.getData();
} catch {
return null;
}
}
// ✅ Return an object
async function getUser(): Promise<{ id: string; name: string }> {
const response = await fetch('/api/user');
return response.json();
}
// ✅ Return an array
async function getUsers(): Promise<User[]> {
const response = await fetch('/api/users');
return response.json();
}Run TypeScript compiler to check for errors:
npx tsc --noEmitOr if using a development server:
npm run devThe error should now disappear. If you're using an IDE, save the file and let the language server re-check it.
Advanced notes
### Type Inference
TypeScript can often infer the Promise return type automatically if you don't annotate it:
// TypeScript infers: Promise<string>
async function getName() {
return 'John';
}However, explicit annotations are recommended for clarity and to catch type errors early.
### Thenable Objects
An async function's return type must be a true Promise or the global Promise type. Custom thenable objects (with a .then method) may not work as expected:
// ❌ May cause issues
async function getPromiseLike(): MyCustomThenable {
return new MyCustomThenable();
}
// ✅ Wrap in Promise
async function getPromiseLike(): Promise<MyType> {
return new Promise((resolve) => {
resolve(new MyCustomThenable());
});
}### Async Generators
If using async generators (returning an AsyncIterable), the syntax is different:
// ✅ Async generator function
async function* generateData(): AsyncGenerator<string, void, unknown> {
yield 'data1';
yield 'data2';
}### TypeScript 4.1+ --noImplicitAny
If you have --noImplicitAny enabled and don't annotate the return type, TypeScript will infer it. Without the flag, you may need explicit annotations to avoid TS7010 (Parameter implicitly has 'any' type).
Frequently asked questions
- What does "TS1058" mean?
- In TypeScript, when you declare a function with the async keyword, the function is guaranteed to return a Promise, even if you don't explicitly return one. The await keyword inside async functions only works with Promises. When you specify a return type annotation for an async function, TypeScript requires that type to be Promise<T> where T is the type of the value being resolved.
- How do I fix "TS1058"?
- This error occurs when you annotate an async function with a non-Promise return type. Async functions always return a Promise, so TypeScript requires you to wrap the return type in Promise<T>.
- What causes "TS1058"?
- Annotating an async function return type without wrapping it in Promise<> (most common) Copy-pasting code from a synchronous function and adding async without updating the return type Misunderstanding that async functions always return Promises, regardless of what you return inside them
- Is the "TS1058" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.