メインコンテンツまでスキップ

noImplicitOverride

noImplicitOverrideはメソッドオーバーライドにoverrideキーワードを必須にするコンパイラオプションです。

  • デフォルト: false
  • 追加されたバージョン: 4.3

解説

サブクラスがスーパークラスのメソッドを拡張したときにoverrideのキーワードをメソッドの前に書くことを強制します。これはスーパークラスの拡張しているメソッドが取り除かれたり、名称が変更されたことを検知することに役立ちます。

たとえば、トグルボタン (クリックするとオン、オフを繰り返すボタン) のクラスが次のようになっているとします。

ts
class ToggleButton {
protected _active: boolean;
 
public constructor() {
this._active = false;
}
 
public get active(): boolean {
return this._active;
}
 
public enable(): void {
this._active = true;
}
 
public disable(): void {
this._active = false;
}
 
public push(): void {
if (this._active) {
this.disable();
// ...
return;
}
this.enable();
// ...
}
}
ts
class ToggleButton {
protected _active: boolean;
 
public constructor() {
this._active = false;
}
 
public get active(): boolean {
return this._active;
}
 
public enable(): void {
this._active = true;
}
 
public disable(): void {
this._active = false;
}
 
public push(): void {
if (this._active) {
this.disable();
// ...
return;
}
this.enable();
// ...
}
}

ここで値のオンオフの切り替えを何回したかを数えられるサブクラスToggleCountButtonを考えます。するとToggleCountButtonは次のようになります。

ts
class ToggleCountButton extends ToggleButton {
private _counter: number;
 
public constructor() {
super();
this._counter = 0;
}
 
public enable(): void {
this._counter++;
this._active = true;
}
 
public disable(): void {
this._counter++;
this._active = false;
}
 
public get counter(): number {
return this._counter;
}
}
ts
class ToggleCountButton extends ToggleButton {
private _counter: number;
 
public constructor() {
super();
this._counter = 0;
}
 
public enable(): void {
this._counter++;
this._active = true;
}
 
public disable(): void {
this._counter++;
this._active = false;
}
 
public get counter(): number {
return this._counter;
}
}

ここでスーパークラスのToggleButtonが「オンオフの切り替えにメソッドはふたつも要らない!セッターで十分だ」と変更されたとします。

ts
class ToggleButton {
protected _active: boolean;
 
public constructor() {
this._active = false;
}
 
public get active(): boolean {
return this._active;
}
 
public set active(active: boolean) {
this._active = active;
}
 
public push(): void {
this._active = !this._active;
// ...
}
}
ts
class ToggleButton {
protected _active: boolean;
 
public constructor() {
this._active = false;
}
 
public get active(): boolean {
return this._active;
}
 
public set active(active: boolean) {
this._active = active;
}
 
public push(): void {
this._active = !this._active;
// ...
}
}

するとサブクラスでオーバーライドしたはずのメソッドenable(), disable()が意味のないメソッドとして残ることになります。

noImplicitOverrideはオーバーライドしているメソッドにoverrideキーワードをつけることによってスーパークラスに同名のメソッドがないかを確認させます。overrideキーワードがついているにもかかわらずオーバーライド元となるメソッドが存在しないと次のようなエラーが発生します。

ts
class ToggleCountButton extends ToggleButton {
private _counter: number;
 
public constructor() {
super();
this._counter = 0;
}
 
public override enable(): void {
This member cannot have an 'override' modifier because it is not declared in the base class 'ToggleButton'.4113This member cannot have an 'override' modifier because it is not declared in the base class 'ToggleButton'.
this._counter++;
this._active = true;
}
 
public override disable(): void {
This member cannot have an 'override' modifier because it is not declared in the base class 'ToggleButton'.4113This member cannot have an 'override' modifier because it is not declared in the base class 'ToggleButton'.
this._counter++;
this._active = false;
}
 
public get counter(): number {
return this._counter;
}
}
ts
class ToggleCountButton extends ToggleButton {
private _counter: number;
 
public constructor() {
super();
this._counter = 0;
}
 
public override enable(): void {
This member cannot have an 'override' modifier because it is not declared in the base class 'ToggleButton'.4113This member cannot have an 'override' modifier because it is not declared in the base class 'ToggleButton'.
this._counter++;
this._active = true;
}
 
public override disable(): void {
This member cannot have an 'override' modifier because it is not declared in the base class 'ToggleButton'.4113This member cannot have an 'override' modifier because it is not declared in the base class 'ToggleButton'.
this._counter++;
this._active = false;
}
 
public get counter(): number {
return this._counter;
}
}