@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
/** @function */
let onSave;
onSave();error TS2722: Cannot invoke an object which is possibly 'undefined'.
export {};jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @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" });
}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
@functionwith 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.tsfile.@methodon 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
- @function · JSDoc
- JSDoc Reference · TypeScript handbook
Last reviewed 20 October 2026.