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

公称型クラス

TypeScriptでは、クラスに1つでも非パブリックなプロパティがあると、そのクラスだけ構造的部分型ではなく公称型(nominal typing)になります。

たとえば、UserIdクラスとGroupIdクラスで同名になってしまっているidプロパティをプライベートにするだけで、相互の代入が不可能になります。

ts
class UserId {
private readonly id: string;
 
constructor(id: string) {
this.id = id;
}
}
 
class GroupId {
private readonly id: string;
 
constructor(id: string) {
this.id = id;
}
}
 
const userId: UserId = new GroupId("...");
Type 'GroupId' is not assignable to type 'UserId'. Types have separate declarations of a private property 'id'.2322Type 'GroupId' is not assignable to type 'UserId'. Types have separate declarations of a private property 'id'.
ts
class UserId {
private readonly id: string;
 
constructor(id: string) {
this.id = id;
}
}
 
class GroupId {
private readonly id: string;
 
constructor(id: string) {
this.id = id;
}
}
 
const userId: UserId = new GroupId("...");
Type 'GroupId' is not assignable to type 'UserId'. Types have separate declarations of a private property 'id'.2322Type 'GroupId' is not assignable to type 'UserId'. Types have separate declarations of a private property 'id'.

この方法はフィールドに限らず、プライベートメソッドやprotectedプロパティでも同じ効果があります。

関連情報

📄️ 構造的型付け

プログラミング言語にとって、型システムは大事なトピックです。型システムとは、プログラム内のさまざまな値や変数に「型」を割り当てる決まりを指します。この決まりによってデータの性質や扱い方が決まります。特に、どのように型と型を区別するのか、逆に、どのように型同士が互換性ありと判断するかは、言語の使いやすさや安全性に直結するテーマです。