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