ESLintでTypeScriptのクラスのpublicやprivateを強制する方法
TypeScriptを使う開発において、コードのメンテナンス性と可読性を保つことは非常に重要です。とくに、大規模なプロジェクトやチームでの開発では、コードの一貫性を保つためのルールが求められます。
この記事では、ESLintと@typescript-eslint
プラグインを使用して、TypeScriptのクラスメンバーに対するアクセシビリティ(public
、protected
、private
)の明示を強制する方法について解説します。
@typescript-eslint/explicit-member-accessibility
ルール
このルールを使うと、TypeScriptのクラスメンバーについて、アクセシビリティを明示的に宣言することを強制できます。これにより、クラスの外部からアクセスできるプロパティやメソッドが明確になり、コードの可読性が向上します。
通常のJavaScriptと違い、TypeScriptではアクセシビリティ修飾子(public
、protected
、private
)を使用できます。
たとえば、次のようにクラスを定義すると、Dog.bark()
メソッドはクラスの外部から呼びだせますが、Dog.eat()
メソッドはクラスの外部から呼びだせません。また、Dog.sleep()
メソッドは、Dog
クラス自身と、Dog
クラスを継承したサブクラスからのみ呼びだせます。
1class Dog {2 constructor(name: string) {3 // ...4 }5
6 public bark() {7 // ...8 }9
10 private eat() {11 // ...12 }13
14 protected sleep() {15 // ...16 }17}
このように、アクセシビリティ修飾子を使用することで、クラスのメンバーに対するアクセスレベルを明確にできます。
こうすることで、外部からの呼びだしを意図していないメソッドやプロパティに対して、誤ってアクセスすることを防げます。さらに、private
なメソッドやプロパティがクラスの内部でのみ使用されることを保証できるため、コードを変更しやすくなります。
アクセシビリティ修飾子を省略した場合、TypeScriptはデフォルトでpublic
として扱います。しかし、アクセシビリティ修飾子が省略されている場合、単なる書き忘れなのか、public
として意図されているのかが分かりにくくなります。
ESLintの@typescript-eslint/explicit-member-accessibility
ルールを使用することで、このようなアクセシビリティ修飾子を明示的に記述することを強制できます。
インストール方法
まず、まだインストールしていない場合はESLintと@typescript-eslint
プラグインをインストールします。
npm install --save-dev eslint @typescript-eslint/eslint-plugin
設定方法
@typescript-eslint
をインストールしたら、プラグインとルールを有効化します。
1{2 "plugins": [3 "@typescript-eslint"4 ],5 "rules": {6 "@typescript-eslint/explicit-member-accessibility": "error"7 }8}
たいていの場合はこれで十分ですが、より詳細な設定も可能です。たとえば、次のようにすると、特定の拡張子をもつファイルに対してのみこのルールを有効にできます。これは、JavaScriptファイルとTypeScriptファイルが混在しているプロジェクトで便利です。
1{2 "rules": {3 // ルールをデフォルトで無効にする4 "@typescript-eslint/explicit-member-accessibility": "off"5 },6 "overrides": [7 {8 // TypeScriptファイルに対してのみ有効にする9 "files": ["*.ts", "*.mts", "*.cts", "*.tsx"],10 "rules": {11 "@typescript-eslint/explicit-member-accessibility": "error"12 }13 }14 ]15}
オプション
explicit-member-accessibility
ルールは、他にもさまざまなオプションでカスタマイズが可能です。たとえば、次の設定では、デフォルトですべてのメンバーにアクセシビリティを明示することを要求し、一部のメンバータイプに対しては特定のアクセシビリティを禁止します。
1{2 "rules": {3 "@typescript-eslint/explicit-member-accessibility": [4 "error",5 {6 "accessibility": "explicit",7 "overrides": {8 "accessors": "explicit",9 "constructors": "no-public",10 "methods": "explicit",11 "properties": "off",12 "parameterProperties": "explicit"13 }14 }15 ]16 }17}
この設定により、プロパティに対してはアクセシビリティの明示を求めず("properties": "off"
)、他のメンバー(アクセサーやメソッドなど)については明示を要求します。また、コンストラクターにpublic
を使用することを禁止します("constructors": "no-public"
)。
コード例
以下は、explicit-member-accessibility
ルールが有効な場合の正しいコードの例と、不適切なコードの例です。
正しいコード例(デフォルト設定):
1class Animal {2 public constructor(public breed, name) {3 this.animalName = name;4 }5
6 private animalName: string;7
8 public get name(): string {9 return this.animalName;10 }11
12 public set name(value: string) {13 this.animalName = value;14 }15
16 public walk() {17 // method18 }19}
不適切なコード例:
1class Animal {2 constructor(name) {3 this.animalName = name;4 }5
6 animalName: string;7
8 get name(): string {9 return this.animalName;10 }11
12 set name(value: string) {13 this.animalName = value;14 }15
16 walk() {17 // method18 }19}
この例では、すべてのクラスメンバーにアクセシビリティ修飾子が欠けています。修飾子を追加することで、クラスの使用方法やメンバーへのアクセスレベルが明確になります。
まとめ
@typescript-eslint/explicit-member-accessibility
ルールを使用することで、TypeScriptのクラスメンバーに対するアクセシビリティ修飾子の明示を強制し、コードの可読性を高めることができます。