公称型クラス
TypeScriptでは、クラスに1つでも非パブリックなプロパティがあると、そのクラスだけ構造的部分型ではなく公称型(nominal typing)になります。
たとえば、UserId
クラスとGroupId
クラスで同名になってしまっているid
プロパティをプライベートにするだけで、相互の代入が不可能になります。
ts
classUserId {private readonlyid : string;constructor(id : string) {this.id =id ;}}classGroupId {private readonlyid : string;constructor(id : string) {this.id =id ;}}constType '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'.: userId UserId = newGroupId ("...");
ts
classUserId {private readonlyid : string;constructor(id : string) {this.id =id ;}}classGroupId {private readonlyid : string;constructor(id : string) {this.id =id ;}}constType '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'.: userId UserId = newGroupId ("...");
この方法はフィールドに限らず、プライベートメソッドやprotected
プロパティでも同じ効果があります。
関連情報
📄️ 構造的部分型
オブジェクト指向。そこまでとはいかなくてもクラスを扱うことができる言語において、ある元となる型(基本型 subtype)という話は欠かすことができません。