How to fix The return type of an async function or method must be the global Promise<T> type in TypeScript

TypeScriptBEGINNERMEDIUMUpdated Dec 8, 2025· 143 views

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;
}
  1. Identify the async function with incorrect type annotation
  2. Wrap the return type in Promise<T>
  3. Handle functions that don't return a value
  4. Use union types for complex return values
typescript — error
async function getUsername(): string { // ❌ Error: TS1058
const 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

  1. Annotating an async function return type without wrapping it in Promise<> (most common)
  2. Copy-pasting code from a synchronous function and adding async without updating the return type
  3. Misunderstanding that async functions always return Promises, regardless of what you return inside them
  4. Using an incorrect Promise type like Promise[] instead of Promise<T>
  5. 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"

1Identify the async function with incorrect type annotation

Look for the function causing the error. It will look something like this:

typescript
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>.

2Wrap the return type in Promise<T>

Change the return type annotation to Promise<T> where T is your original type:

typescript
// ✅ 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.

3Handle functions that don't return a value

If your async function doesn't return a value, use Promise<void>:

typescript
// ❌ 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);
}
4Use union types for complex return values

If your async function can return different types, use a union type inside Promise:

typescript
// ✅ 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();
}
5Verify the fix compiles

Run TypeScript compiler to check for errors:

bash
npx tsc --noEmit

Or if using a development server:

bash
npm run dev

The 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
// 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:

typescript
// ❌ 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:

typescript
// ✅ 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.

Official resources & further reading