せつめい
人間から見るとそんなに複雑ではないように見える定義でも、結果的に膨大な量の列挙になってしまうような型を定義しようとするとエラーになるようです。
エラーになったコード
#FF8800
というようなカラーコードを表現する型を定義しようとしたのですが、ムリでした。
どうやら、#000000
~#FFFFFF
の16,777,216個ぶんすべての型を単純に結合したUnionを定義することになってしまうようです。
(…カラーコードの横に自動で色が表示されてる!?)
type NumChar1 = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
type HexChar1 = NumChar1 | "a" | "b" | "c" | "d" | "e" | "f";
type HexChar2 = `${HexChar1}${HexChar1}`;
type ColorCode6 = `#${HexChar2}${HexChar2}${HexChar2}`; // エラーになる
type ColorCode3 = `#${HexChar1}${HexChar1}${HexChar1}`; // エラーにならない
tscで出力されるエラー
test.ts:5:19 - error TS2590: Expression produces a union type that is too complex to represent.
5 type ColorCode6 = `#${HexChar2}${HexChar2}${HexChar2}`;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
VSCode上のポップアップ1
type ColorCode6 = any
VSCode上のポップアップ2
type HexChar2 = "dd" | "aa" | "ab" | "a0" | "a1" | "a2" | "a3"
| "a4" | "a5" | "a6" | "a7" | "a8" | "a9" | "ac" | "ad" | "ae"
| "af" | "ba" | "bb" | "b0" | "b1" | "b2" | "b3" | "b4" | "b5"
| "b6" | "b7" | ... 228 more ... | "ff"
式は、複雑すぎて表現できない共用体型を生成します。ts(2590)
なお、#F808
の4ケタまでならなんとか大丈夫みたい。5ケタからエラーになります。
type ColorCode4 = `#${HexChar1}${HexChar1}${HexChar1}${HexChar1}`;
VSCode上のポップアップ
type ColorCode4 = "#2343" | "#aaaa" | "#aaab" | "#aaac" | "#aaad"
| "#aaae" | "#aaaf" | "#aaa0" | "#aaa1" | "#aaa2" | "#aaa3"
| "#aaa4" | "#aaa5" | "#aaa6" | "#aaa7" | "#aaa8" | "#aaa9"
| "#aaba" | ... 65517 more ... | "#9999"
今回の対処法
先頭に#
がついてるstring
はぜんぶカラーコード扱いにすることで妥協しました(かなしみ)
type ColorCode = `#${string}`; // #[0-9a-f]{6} だとエラーになる
const notColorString: ColorCode = "######🤪🤪🤪"; // 特にエラーにならない
参考ページ