@override on a class member says it replaces a member of the base class. TypeScript checks the claim: an @override on a method the base class does not have is an error (TS4122), which catches a rename in the base class that left a subclass method orphaned.
With noImplicitOverride in jsconfig.json, the check also runs the other way: every member that overrides one in the base class must carry the tag (TS4119). That is the JavaScript form of TypeScript's override keyword, with the same noImplicitOverride option.
At a glance
| Use | JSDoc in a .js file | TypeScript in a .ts file |
|---|---|---|
| An overriding method | /** @override */
area() { … } | override area() { … } |
| Require it everywhere | "noImplicitOverride": true | "noImplicitOverride": true |
Examples
export class Shape {
/** @returns {number} */
area() {
return 0;
}
}
export class Circle extends Shape {
/** @param {number} radius */
constructor(radius) {
super();
this.radius = radius;
}
/** @override */
area() {
return Math.PI * this.radius ** 2;
}
}export class Shape {
area(): number {
return 0;
}
}
export class Circle extends Shape {
radius: number;
constructor(radius: number) {
super();
this.radius = radius;
}
override area() {
return Math.PI * this.radius ** 2;
}
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"noImplicitOverride": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} export class Shape {
/** @returns {number} */
area() {
return 0;
}
}
export class Square extends Shape {
side = 2;
area() {error TS4119: This member must have a JSDoc comment with an '@override' tag because it overrides a member in the base class 'Shape'.
return this.side ** 2;
}
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"noImplicitOverride": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} export class Shape {
/** @returns {number} */
area() {
return 0;
}
}
export class Square extends Shape {
side = 2;
/** @override */
perimeter() {error TS4122: This member cannot have a JSDoc comment with an '@override' tag because it is not declared in the base class 'Shape'.
return this.side * 4;
}
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} The two checks
The check on tagged members is always on: the third example has no noImplicitOverride and still fails, because perimeter() overrides nothing. The check on untagged members needs the option: the second example sets it, and the area() without a tag fails.
The JavaScript messages name the JSDoc tag: "This member must have a JSDoc comment with an '@override' tag…" and "This member cannot have a JSDoc comment with an '@override' tag…". In a .ts file the same checks talk about the override modifier.
Where the tag goes
In the member's own JSDoc comment, on the lines above it. In our tests, a comment written on the same line as the class's opening brace (class Circle extends Shape { /** @override */ area() …) was not attached to the method, so the tag had no effect.
Gotchas
- The
overridekeyword is TypeScript syntax: in a.jsfile it is an error (TS8009). - The
overridekeyword andnoImplicitOverridearrived with TypeScript 4.3; the release notes do not date the JSDoc tag, and the examples on this page are checked with TypeScript 5.9.
Questions
Do I need noImplicitOverride to use @override?
No. A wrong @override is reported without it. The option only adds the reverse check, that every override is tagged.
Sources
- JSDoc Reference: @override · TypeScript handbook
- TypeScript 4.3: override and the --noImplicitOverride flag · TypeScript release notes
- @override · JSDoc
Last reviewed 20 October 2026.