These four JSDoc tags record facts about the code for the people who read it: who wrote it, the release it first appeared in, its version, and what is left to do. TypeScript 5.9 keeps them in the comment and shows them in editor hovers, under the signature. None of them changes what tsc reports.
They work the same in .js and .ts files. The one detail TypeScript cares about is the email address in @author: put it in angle brackets, or part of it will be read as a separate tag.
At a glance
| Use | JSDoc in a .js file | TypeScript in a .ts file |
|---|---|---|
| Who wrote it | /** @author Jane Doe <jane@example.com> */ | /** @author Jane Doe <jane@example.com> */ |
| When it appeared | /** @since 1.4.0 */ | /** @since 1.4.0 */ |
| Its version | /** @version 2.0.0 */ | /** @version 2.0.0 */ |
| Work still to do | /** @todo handle other scripts */ | /** @todo handle other scripts */ |
Examples
/**
* Turns a product name into a URL slug.
*
* @author Jane Doe <jane@example.com>
* @since 1.4.0
* @version 2.0.0
* @todo handle names in scripts other than Latin
* @param {string} name
* @returns {string}
*/
export function slugify(name) {
return name
.toLowerCase()
.trim()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-|-$/g, "");
}
slugify("Cotton Tee, Large");jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} // Hover normalizeCode: TypeScript shows an author tag reading "Jane Doe jane"
// and an example tag reading ".com", because the email is not in angle brackets.
/**
* Lowercases a product code.
*
* @author Jane Doe jane@example.com
* @param {string} code
*/
export function normalizeCode(code) {
return code.toLowerCase();
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} The email address in @author
TypeScript's JSDoc parser starts a new tag at an @. In @author Jane Doe <jane@example.com> the angle brackets keep the address together, and the hover shows the name and the address. Without them, jane@example.com is split: the hover shows an @author tag reading "Jane Doe jane" and an @example tag reading ".com", as the second example shows.
We checked that split with TypeScript's language service, the same code editors call for hovers: the tags it returns for the second example are author and example. VS Code then prints the address without the angle brackets.
What editors show
Hovers list these tags below the description, each as its name followed by its text. @since and @version are free text: TypeScript does not compare them with your package.json or with each other.
@todo is easy to lose in a hover. If you want open work to be visible, a linter rule or your issue tracker is a better home; the tag is fine as a pointer next to the code.
Gotchas
- Any word after an
@inside a JSDoc comment can be read as a tag. Write an@in prose as part of a code span or reword the sentence. - TypeScript treats
@since,@versionand@todoas unknown tags. That is normal: unknown tags are kept and shown, never reported.
Questions
Does TypeScript check @since against the TypeScript or package version?
No. @since is text. To say a declaration is going away, use @deprecated, which editors do act on.
Sources
- JSDoc Reference: @author · TypeScript handbook
- @author · JSDoc
- @since · JSDoc
- @version · JSDoc
- @todo · JSDoc
Last reviewed 20 October 2026.