値オブジェクト(DDD用語)
DDD用語でエンティティと値オブジェクトというのがあって、
という。
TSでこんな感じの型を作り、値オブジェクトとして扱いたいとする
// 名前を表す値オブジェクトにしたい export type Name = Readonly<{ firstName: string; lastName: string; }>; // Name型のオブジェクトを生成する関数 export const createName = (firstName: string, lastName: string): Name => ({ firstName, lastName });
しかし === 演算子を使って同じプロパティを持つオブジェクトを比較ししてもTS/JSではfalseになる。
const name1 : Name = createName('John', 'Doe'); const name2 : Name = createName('John', 'Doe'); // JavaScriptではオブジェクト同士の比較は、同じプロパティを持っていても参照が異なるため、falseになる expect(name1 === name2).toBe(false);
なので、Name型のオブジェクトを比較する関数を用意する。
// Name型のオブジェクトを比較する関数 export const isNameEqual = (name1: Name, name2: Name): boolean => { return name1.firstName === name2.firstName && name1.lastName === name2.lastName; }; expect(isNameEqual(name1, name2)).toBe(true);
比較用の関数を用意しないといけないのが、型が増えると大変そう。
他の言語だと
F#だとデフォルトでプロパティがすべて同じならオブジェクトが等しいとみなす、構造的等値性という声質を持つ。 Kotlinだとdata classがある。Scala, Java, C#でも同じような機能がある。
TSだとそれがないので不便に感じた。TSでもdata class的なものをシュッと作れる方法がないのかな。