https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#ecmascript-private-fields [[TypeScript]]における[[Private class features]]は`private宣言子`と若干挙動が異なる。 ## 挙動の違い `public`, `private宣言子`, `Private Fields`の違いについて。 ### public(デフォルト) 親クラスのメソッドが参照するフィールドは、上書きされた子クラスの同名フィールドになる。 ```ts class Parent { name = "parent"; getParentName(): string { return this.name; } } class Child extends Parent { name = "child"; getChildName(): string { return this.name; } } console.log(new Child().getParentName()); // -> child console.log(new Child().getChildName()); // -> child ``` ### private宣言子 同名のprivateフィールドが存在するとエラーになる。 ```ts class Parent { private name = "parent"; getParentName(): string { return this.name; } } // main.ts:9:7 - error TS2415: Class 'Child' incorrectly extends base class 'Parent'. // Types have separate declarations of a private property 'name'. class Child extends Parent { private name = "child"; getChildName(): string { return this.name; } } console.log(new Child().getParentName()); console.log(new Child().getChildName()); ``` また、`private`修飾子はコンパイル時にのみ考慮され、実行時には一切考慮されない。すなわち、一度`.js`ファイルにコンパイルされると通常の公開プロパティとして動作する。 ### Private Fields メソッドが定義されたクラスのプライベートフィールドを参照する。 ```ts class Parent { #name = "parent"; getParentName(): string { return this.#name; } } class Child extends Parent { #name = "child"; getChildName(): string { return this.#name; } } console.log(new Child().getParentName()); // -> parent console.log(new Child().getChildName()); // -> child ``` `private`修飾子と異なり、Private Fieldsはコンパイル後の`.js`ファイルでもprivate性が保証される。つまり、`.js`ファイルの実行時でもPrivate Fieldsにはアクセスできない。 ## MOC - [[TypeScriptでECMAScript Private Fieldsを使うべきかどうか]]