TypeScriptでPhantomType(幽霊型)を実装する3つのパターン
TypeScriptでPhantomType(幽霊型)を実装する3つのパターン
TypeScriptで幽霊型を実装するパターンをまとめました。
すべて、**元の「プリミティブ」に「形式的にオブジェクトを付加する」**ことで幽霊型を実現しています。
1. {unique symbol: never}
declare const P1_1US: unique symbol;
type P1_1 = string & { [P1_1US]: never };
declare const P1_2US: unique symbol;
type P1_2 = string & { [P1_2US]: never };
const P1func = (p: P1_1): void => {};
P1func('aaa'); //エラー
P1func('aaa' as P1_1); //OK
P1func('aaa' as P1_2); //エラー
メリット
型として一番綺麗?
デメリット
1つ1つの方ごとに、unique symbolを定義しないといけないので、面倒
2. {unique symbol: string}
declare const P2: unique symbol;
type P2_1 = string & { [P2]: 'P2_1'};
type P2_2 = string & { [P2]: 'P2_2'};
const P2func = (p: P2_1): void => {};
P2func('aaa'); //エラー
P2func('aaa' as P2_1); //OK
P2func('aaa' as P2_2); //エラー
メリット
unique symbolの定義が1つだけで済む
デメリット
ユニークな文字列を振らないといけない(「P2_1」「P2_2」の部分)
3. {string: never}
type P3_1 = string & { __P3_1__: never};
type P3_2 = string & { __P3_2__: never};
const P3func = (p: P3_1): void => {};
P3func('aaa'); //エラー
P3func('aaa' as P3_1); //OK
P3func('aaa' as P3_2); //エラー
メリット
定義が楽
デメリット
ユニークな文字列を振らないといけない(「__P3_1__」「__P3_2__」の部分)