TypeScript error

TS2355: A function with a return type never returns a value

  • Error TS2355
  • Tested with TypeScript 5.9

error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. is reported when a function's return type is declared, by @returns or by a @type tag on the function, and its body contains no return statement with a value at all. In a .js file the error is reported on the type inside the JSDoc tag.

The usual cause is a function that computes its result and forgets to hand it back. A less obvious one is a @type tag that types the whole function, such as a framework's handler type with a non-void return; the Express handler recipe shows that case.

At a glance

CodeTS2355
MessageA function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.
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).

What it looks like

slug.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: slug.js(2,37): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. slug.js(2,37): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. slug.js(2,37): error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value. checked 21 October 2026
/** @param {string} title @returns {string} */error TS2355: A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.
export function slugify(title) {
  title.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-");
}
A function whose @returns promises a value it never returns.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

What causes it

  • The body does the work but never says return value (a .map, .replace or template string whose result is dropped).
  • A @type on a function expression or arrow function declares a function type whose return type is not void, and the body is written as if it returns nothing.

How to fix it

Return the value

Add the return. In the example the string methods produce a new string and the function drops it.

slug.js 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} title
 * @returns {string}
 */
export function slugify(title) {
  return title.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-");
}

/**
 * @param {string} title
 * @returns {void}
 */
export function logTitle(title) {
  console.log(title.trim());
}
Return the value, or say the function returns nothing.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Or declare that the function returns nothing

If the function is called for its side effect, change the tag to @returns {void}, or remove @returns and let the checker infer void. For a handler typed with @type, use @param tags or @satisfies instead, so the return type comes from the body.

Gotchas

  • If some paths return a value and others fall off the end, the error is TS2366 instead.
  • @returns {Promise<string>} on an async function requires a return with a string; an async function that only awaits work is Promise<void>.

Sources

Last reviewed 20 October 2026.