Type expression

Function types

  • Functions
  • Tested with TypeScript 5.9

A function type describes a function's parameters and return type. TypeScript's arrow syntax works inside JSDoc braces unchanged: @param {(a: Product, b: Product) => number} compare. The parameter names are for readers; only the types and their order are checked.

The Closure Compiler form, {function(number, string=): string}, also works: parameters are listed by type only, = marks an optional one, and the return type follows a colon. The arrow form is the one TypeScript uses in its messages.

At a glance

Use JSDoc in a .js file TypeScript in a .ts file
Arrow syntax /** @type {(amount: number, currency?: string) => string} */ : (amount: number, currency?: string) => string
Closure syntax /** @type {function(number, string=): string} */ : (amount: number, currency?: string) => string
A callback parameter /** @param {(a: Product, b: Product) => number} compare */ (compare: (a: Product, b: Product) => number)
Any function /** @type {Function} */ : Function

Examples

sort.js sort.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
/** @typedef {{ sku: string, price: number }} Product */

/** @type {(amount: number, currency?: string) => string} */
export const formatPrice = (amount, currency = "USD") =>
  new Intl.NumberFormat("en-US", { style: "currency", currency }).format(amount);

/**
 * @param {Product[]} products
 * @param {(a: Product, b: Product) => number} compare
 */
export function sorted(products, compare) {
  return [...products].sort(compare);
}

sorted([{ sku: "TEE-01", price: 19.5 }], (a, b) => a.price - b.price);
formatPrice(19.5);
type Product = { sku: string; price: number };

export const formatPrice: (amount: number, currency?: string) => string = (amount, currency = "USD") =>
  new Intl.NumberFormat("en-US", { style: "currency", currency }).format(amount);

export function sorted(products: Product[], compare: (a: Product, b: Product) => number) {
  return [...products].sort(compare);
}

sorted([{ sku: "TEE-01", price: 19.5 }], (a, b) => a.price - b.price);
formatPrice(19.5);
Function types in arrow syntax.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
format.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 : differs, see why TypeScript 7.0.2, run 21 October 2026: differs from 5.9.3. format.js(1,20): error TS1005: '}' expected. format.js(2,29): error TS7006: Parameter 'amount' implicitly has an 'any' type. format.js(2,37): error TS7006: Parameter 'currency' implicitly has an 'any' type. format.js(5,21): error TS1005: '}' expected. format.js(7,38): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type 'Function' is not assignable to parameter of type '(value: string, index: number, array: string[]) => unknown'. Type 'Function' provides no match for the signature '(value: string, index: number, array: string[]): unknown'. format.js(11,16): error TS7006: Parameter 'sku' implicitly has an 'any' type. checked 21 October 2026
/** @type {function(number, string=): string} */
export const formatPrice = (amount, currency) =>
  new Intl.NumberFormat("en-US", { style: "currency", currency: currency ?? "USD" }).format(amount);

/** @param {function(string): boolean} test */
export function countMatching(test) {
  return ["TEE-01", "MUG-07"].filter(test).length;
}

formatPrice(19.5);
countMatching((sku) => sku.startsWith("TEE"));
The older Closure spelling, function(…): ….
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
sort.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: sort.js(10,42): error TS2322: Type 'boolean' is not assignable to type 'number'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. sort.js(10,42): error TS2322: Type 'boolean' is not assignable to type 'number'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. sort.js(10,42): error TS2322: Type 'boolean' is not assignable to type 'number'. checked 21 October 2026
/**
 * @param {string[]} skus
 * @param {(a: string, b: string) => number} compare
 */
export function sortSkus(skus, compare) {
  return [...skus].sort(compare);
}

sortSkus(["MUG-07", "TEE-01"], (a, b) => a > b);error TS2322: Type 'boolean' is not assignable to type 'number'.
A function that does not fit the declared type.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Typing a function value

@type with a function type on a const types the parameters of the function assigned to it, so the arrow function needs no @param tags. For a function declaration, @param and @returns are the usual route.

Callbacks passed inline take their parameter types from the function type they are passed to, as (a, b) => a.price - b.price does in the first example.

The Function type

{Function} (and {function} in lowercase) accepts any function and returns any when called, so it checks almost nothing. Prefer a specific function type, or (...args: never[]) => unknown when you only need "some function".

Under TypeScript 6.0 and 7.0

Every example on this page also runs under TypeScript 6.0.3 and 7.0.2 when this site is built. One of them reports something different from 5.9.3, the version the page describes; the ✗ on its badge links to its entry below.

Closure function types do not parse

TypeScript 7.0 · JSDoc and JavaScript patterns 7.0 no longer reads

The pattern: {function(string): boolean}, {function(number, string=): string} and {function(new: Date, string)} in JSDoc.

Why: The port's list of changes removes Closure function types from the JSDoc parser. The type is a syntax error (TS1005), so the parameters it should type are untyped (TS7006 under strict) and calls through it fail (TS2769, TS2351). Source: CHANGES.md: changes between TypeScript 6 and the native port.

The older Closure spelling, function(…): … format.js

TypeScript 5.9.3

No errors.

TypeScript 6.0.3same as 5.9.3

No errors.

TypeScript 7.0.2differs from 5.9.3
format.js(1,20): error TS1005: '}' expected.
format.js(2,29): error TS7006: Parameter 'amount' implicitly has an 'any' type.
format.js(2,37): error TS7006: Parameter 'currency' implicitly has an 'any' type.
format.js(5,21): error TS1005: '}' expected.
format.js(7,38): error TS2769: No overload matches this call.
  The last overload gave the following error.
    Argument of type 'Function' is not assignable to parameter of type '(value: string, index: number, array: string[]) => unknown'.
      Type 'Function' provides no match for the signature '(value: string, index: number, array: string[]): unknown'.
format.js(11,16): error TS7006: Parameter 'sku' implicitly has an 'any' type.

What works in every version: Arrow syntax: {(sku: string) => boolean}, {(amount: number, currency?: string) => string}, {new (iso: string) => Date}.

The example Function types in arrow syntax on this page shows it, with the same result under every version.

Gotchas

  • A callback that returns the wrong type is reported inside the callback: (a, b) => a > b returns a boolean where number is expected, and the error points at a > b (TS2322).
  • A function with fewer parameters than the type is fine: (a) => … can be passed where (a, b) => … is expected, as in JavaScript.
  • TypeScript 7.0 does not parse the Closure spelling function(string): number (the section Under TypeScript 6.0 and 7.0 has what 7.0.2 reports); the arrow spelling works in every version.

Questions

How do I write a function type in JSDoc?

Use arrow syntax inside the braces: {(input: string) => boolean}. For a reusable name, put it in a @typedef or write a @callback.

Sources

Last reviewed 21 October 2026.