TypeScriptで同じ構造の型を区別する
モチベーション
TypeScriptで同じ構造の型を区別したい
例えば、以下のようなもの
UserId
と PostId
という2つの型を定義している
しかし、TypeScriptは
構造的部分型を採用しているため、これらは区別されない
tstype UserId = number;
type PostId = number;
const userId: UserId = 888;
const postId: PostId = 24;
const register = (userId: UserId, postId: PostId) => {...}
register(postId, userId) // 引数の順番をミスっているがerrorにならない
いくつかの実現方法
libraryを使う
これはだいぶ簡易
tstype Id<T extends string> = {
type: T,
value: string,
}
いくつかの問題を抱えていると思う

値の構造が変わっているのでruntimeに影響がある
constructorがなくとも容易にその構造を作成できてしまう
構造が貧弱なので、たまたま被る可能性が高い
応用
「同じ構造をの型を別物として扱う」ことで、設計を堅牢にする様々な工夫ができるようになる
上の「モチベーション」は本当に表層のことしか書いていない

Nominal Subtypingをサポートしてくれという趣旨のissueが2014/7/23に立てられている
ずっとopenになってる
この辺との違い
幽霊型では、タグとして引数に与えるのは基本的に型だが、
TypeScriptではstring literal typeを与えることが多い
タグが重複すれば同等のものになる、という特性はbranded typeも同じ
newtypeはそもそも新しい型を生成する
TypeScriptでは無理
TypeScriptでは元々用意されているprimitive型のsubtypingでしか新しい型を定義できない