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>.
Fixes TS1058
async function getUsername(): string { // ❌ Error: TS1058
const user = await fetchUser();
return user.name;
}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
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.
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.
### 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).