JSDoc tag

@function, @func and @method

  • Not checked by TypeScript
  • Tested with TypeScript 5.9
  • Alias @func
  • Alias @method

@function (also @func and @method) is a JSDoc documentation tag that says the documented thing is a function, for cases the documentation tool cannot work out on its own. TypeScript 5.9 does not read it, and it does not need to: a function declaration or a function expression already has a function type.

When a variable will hold a function later, declare its type with @type. The tag does not do that: a let tagged @function is still typed by what is assigned to it, and calling it before an assignment is an error.

At a glance

Use JSDoc in a .js file TypeScript in a .ts file
A variable that holds a function /** @type {(() => void) | undefined} */ let onSave; let onSave: (() => void) | undefined;

Examples

save.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: save.js(5,1): error TS2722: Cannot invoke an object which is possibly 'undefined'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. save.js(5,1): error TS2722: Cannot invoke an object which is possibly 'undefined'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. save.js(5,1): error TS2722: Cannot invoke an object which is possibly 'undefined'. checked 21 October 2026
/** @function */
let onSave;

onSave();error TS2722: Cannot invoke an object which is possibly 'undefined'.

export {};
@function does not give a variable a function type.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
save.js save.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
/** @type {((draft: { title: string }) => void) | undefined} */
let onSave;

/** @param {(draft: { title: string }) => void} handler */
export function setSaveHandler(handler) {
  onSave = handler;
}

export function save() {
  onSave?.({ title: "Spring sale" });
}
let onSave: ((draft: { title: string }) => void) | undefined;

export function setSaveHandler(handler: (draft: { title: string }) => void) {
  onSave = handler;
}

export function save() {
  onSave?.({ title: "Spring sale" });
}
Give the variable a function type with @type.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

How we tested it

The first example declares let onSave; under @function and calls it. If the tag gave the variable a function type, the call would pass. tsc reports TS2722 ("Cannot invoke an object which is possibly 'undefined'"), the same as without the tag, so the tag is not read. We saw the same result for @func and @method.

Typing variables that hold functions

@type {(draft: { title: string }) => void} gives the variable a function type, and | undefined admits that it may not be set yet. Callers then use onSave?.(…), and every function assigned to it is checked against the signature.

Gotchas

  • @function with a name (@function formatPrice) documents a function that does not appear in the code. TypeScript does not create anything from it; declare the function or write a .d.ts file.
  • @method on a class method is harmless but unnecessary: TypeScript already knows it is a method.

Questions

How do I type a variable as a function in JSDoc?

With @type and a function type: /** @type {(event: Event) => void} */. A named type from @callback or @typedef works the same way.

Sources

Last reviewed 20 October 2026.