TypeScript で string 型の値に自動補完を効かせる ― 2021年09月11日 12時12分
結論
type X = 'foo' | 'bar' | (string & {});
のように、文字列リテラル型の共用体型に | (string & {})
を付け足した型 X
を定義します。X
型は任意の文字列を受け付けますが、IDE (Visual Studio Code など) で X
型の値を入力するときには 'foo'
と 'bar'
が自動補完の候補として提示されます。
解説
単純に type X = 'foo' | 'bar' | string;
と書いてしまうと、共用体型の各要素がまとめられて、X
は単なる string
型になってしまいます。{}
型は null
と undefined
を除く任意の値を受け付けるので、string & {}
型は実質的に string
型と同一なのですが、TypeScript 4.4 の時点では同一扱いされず、共用体型の各要素がまとめられることもありません。
この手法を知った経緯
React の型定義の変更履歴を見たところ、input
要素の type
属性の型定義を追加するという変更が入っていました。そこには見慣れない表記が交じっており、コメントには「| (string & {})
ハック」と書かれています。
input
要素の type
属性 (HTMLInputElement
インターフェイスの type
プロパティ) には、形式的には任意の文字列を指定できますが、実際に有効なのは text
、checkbox
、radio
など特定の値のみです。type
プロパティの値を指定するときに、自動補完を使ってミスなく高速に入力したいというのは自然な考えでしょう。
しかし、type
プロパティの型を string
型から文字列リテラル型の共用体型に変えてしまうと、これまで指定できていた値が指定できなくなったり、将来の input
要素の拡張に即座に対応できなくなったりと、互換性が失われてしまいます。型の互換性を維持しつつ IDE の入力支援を引き出すために、| (string & {})
ハックが生み出されたのだと思います。
最近のコメント