Typescriptクラスのアクセス制御
多くのプログラミング言語では、クラスのプロパティがデフォルトでプライベートとして定義されています。インスタンスの外部からアクセスできるようにするには、通常、関連するプロパティをキーワード「public」でマークする必要があります。
同じキーワードはTypescriptクラスでも使用できますが、Typescriptクラスのプロパティはデフォルトで公開されているため、あまり影響はありません。この制約は、クラスのプライベートプロパティをサポートしないJavascriptから継承されます。さて、最近まで。
Javascriptのプライベートフィールド?
はいといいえ。現在、Javascriptクラスでプライベートプロパティを定義する仕様の作業ドラフトはステージ3にあります。これは、最終的な定義が妥当であることを示していますが、まだ確実ではありません。
仕様の提案された変更は本当に単純で、構文をわずかに変更するだけです。プロパティをプライベートとしてマークするには、ハッシュタグをプレフィックスとして付けるだけです。それでおしまい!
class User {
// A prop marked as private.
#id;
age;
constructor(age){
this.age = age;
// Valid assignment, as we're
// within the class.
this.#id = Math.floor(Math.random() * 1000);
}
}
// ... Later in the code ...
const user = new User(42);
// Error! Won't work as it's private.
user.#id = 123;
Typescriptのプライベートフィールド!
Typescriptのプライベートプロパティにもまったく同じ構文が適用されます。バージョン3.8以降、この機能を使用して、インスタンスおよび静的フィールドのプロパティと関数へのアクセスをより適切に制御できます。構文はJavascriptの例と同じです。
ちょっと待ってください、プライベート静的フィールド?
はい、正しくお読みください。静的変数と関数はプライベートにすることもできます。つまり、クラスのメンバー内でのみ呼び出すことができます。この機能は、Typescriptバージョン4.3で追加され、内部でさらに変更が加えられました。バージョン4.3のドキュメントによると、プライベートクラスのメンバーは実行時に完全にプライベートになりました。これは、この機能が完全に成熟したことを示しています。
Typescriptは、クラスの「プライベート」の2つの異なるバリアントをサポートしていることに注意してください。一般的に知られているのは、キーワード「private」を使用することです。これにより、派生クラスからでもマークされたフィールドにアクセスできなくなります。
ここで紹介している新しい機能であるもう1つの機能は、いわゆる「プライベート名」の使用法です。それらの仕様は元々JSによって定義されていたため、これらはJavascriptの場合と同じ構文です。 Typescriptでは、実行時にアクセスを制御します。
/**
* A class that uses already known
* private props.
*/
class CommonUser {
// Common 'private' prop in TS.
private id: number;
age: number;
constructor(age: number){
this.age = age;
this.id = Math.floor(Math.random() * 1000);
}
}
/**
* Using the new sytanx for private class names.
*/
class SpecialUser {
#id: number;
age: number;
constructor(age: number){
this.age = age;
// Valid, we're inside the class.
this.#id = SpecialUser.#generateId();
}
static #generateId(){
return Math.floor(Math.random() * 1000);
}
#stringifyId(){
return this.#id.toString();
}
}
// ... Later in the code ...
// Invalid, call is outside of class 'SpecialUser'.
SpecialUser.#generateId();
const user = new SpecialUser(42);
// And that won't work as well.
user.#stringifyId();
最後の章の最後の言葉
この記事はそれほど長くはありませんが、Typescriptが現在提供している優れた機能と、Typescript自体のより一般的な利点に焦点を当てています。 Javascriptの場合、プライベートプロパティはまだドラフトですが(非常に遅い段階ですが)、Typescriptの場合、それらはすでに実装されて出荷されており、この言語が進化している速度を示しています。