公称型クラス
TypeScriptでは、クラスに1つでも非パブリックなプロパティがあると、そのクラスだけ構造的部分型ではなく公称型(nominal typing)になります。
たとえば、UserIdクラスとGroupIdクラスで同名になってしまっているidプロパティをプライベートにするだけで、相互の代入が不可能になります。
typescriptclass 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'.(2322)
typescriptclass 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'.(2322)
この方法はフィールドに限らず、プライベートメソッドやprotectedプロパティでも同じ効果があります。