Branded Type

ScalaでOpaque Type, Newtypeと呼ばれるパターンを再現する。

declare const UserIdSymbol: unique symbol;
type UserId = string & { [UserIdSymbol]: never };
 
// ⭕ 明示的にキャストが必要
const me: UserId = "me" as UserId;
// ❌ 暗黙キャストはされない
const you: UserId = "you";
 
// ⭕
const show: string = me;
 
declare const PostIdSymbol: unique symbol;
type PostId = string & { [PostIdSymbol]: never };
 
// ❌ 異なる型へは代入できない
const postId0: PostId = me;
// ❌ キャストもできない
const postId1: PostId = me as PostId;
// ⭕ stringを経由する
const postId2: PostId = me as string as PostId;

クラスを使わない

  • JSのthisの挙動が混乱する
  • POJOと互換性がない。JSONと相互運用が難しい。
export type Post = {
  id: string;
};
// コンパニオンオブジェクト
export const Post = {
  make(name: string): Post {
    const id = generateId();
    return {
      id,
    };
  },
  destroy(this: Post) {
    todo();
  },
};
 
// private method相当
function generateId() {
  todo();
}