TypeScriptで自由な文字列を受け入れつつUnion型を保つ
https://gyazo.com/1ab476170d4de960550ff06c6d49a764
追記: 後から気づいたんですが、これ幽霊型(Phantom Type)のアプローチと同じですね
あとTS4.2の機能で解決するかもしれんわね
追記2
TS の branded type を幽霊型と呼ぶの厳密には誤りなんだけどその誤りを広めてしまったのたぶん私なんだよなーとなっている
実は、Branded typeと呼ぶのがいいらしい
複数の文字列の組み合わせからどれか一つを選ばせたい時、TypeScriptではtype ValueUnion = "value1" | "value2"のようにすることで文字列のUnion型を作ることができる。
このとき加えて自由な文字列を受け入れたいとなるとtype ValueUnion = "value1" | "value2" | stringとする必要があるが、こうするとたちまちValueUnion = stringとなってしまい、入力時の型補完も効かなくなる上にextendsで拡張をチェックすることもできなくなる。
この問題はTypeScriptのIssueとして既に上がっている このコメントによると、これはtype ValueUnion = "value1" | "value2" | (string & {})のようにすることで解決できる "value1"等通常の文字列は全てstring型なのでUnionさせてしまうと合成されてしまうが、string & {}であればstringの性質そのものにはに影響を与えずstring以外の定義になるので合成されない
追記
このエントリの初版はStringを用いるものでした
/rokoucha/rokoucha.iconから非推奨型だから解法としては適切ではないよな〜という指摘を受けた
@ci7lus