TypeScript error

TS1064: An async function whose return type is not a Promise

  • Error TS1064
  • Tested with TypeScript 5.9

An async function always returns a promise, whatever its body returns. So its annotated return type has to be Promise<…>: @returns {string} on an async function is TS1064, and the message suggests the right spelling.

In a .js file the error is reported on the type in the @returns tag, so the fix is in the comment, not in the code.

At a glance

CodeTS1064
MessageThe return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<{0}>'?
TypeScript's categoryerror
Listed underTypes do not match
Turned on by No option: every checked file reports it
In .js files Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file

The message is TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} is filled in by tsc for each error.

What it looks like

text.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: text.js(2,35): error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<string>'? 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. text.js(2,35): error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<string>'? 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. text.js(2,35): error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<string>'? checked 21 October 2026
/** @param {string} url @returns {string} */error TS1064: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<string>'?
export async function fetchText(url) {
  const response = await fetch(url);
  return response.text();
}
An async function whose @returns is not a Promise.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["**/*.js"]
}

What causes it

  • The @returns tag describes the value the function body returns rather than what callers receive.
  • A function was made async later and its JSDoc was not updated.

How to fix it

Wrap the type in Promise

Write @returns {Promise<string>}. Callers then await a string, which is what the code already did.

text.js text.ts TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/**
 * @param {string} url
 * @returns {Promise<string>}
 */
export async function fetchText(url) {
  const response = await fetch(url);
  return response.text();
}
export async function fetchText(url: string): Promise<string> {
  const response = await fetch(url);
  return response.text();
}
@returns {Promise<string>} on an async function.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["**/*.js"]
}

Gotchas

  • Leaving @returns out also works: TypeScript infers Promise<string> from the body. Exported functions read better with the tag.
  • The type must be the global Promise; a promise-like class from a library is not accepted as an async function's return type.

Sources

Last reviewed 21 October 2026.