UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【TypeScript】SymbolでIDを公称型にする

TypeScriptで元はstringだが型定義したIDを作りたいとき

type AreaId = string;

のように定義していたが、TypeScriptは構造的な部分一致により同一の型かどうかを判断しているので、これではどんなstringの文字列も通してしまう

そこで厳密に区別される仕組みがないかを調べた

qiita.com

上の記事を参考にすると、特定のID型を簡単に作るには Symbolを使って以下のようにするのがよいみたい

const id = Symbol();
type AreaId = string & { [id]: never };

シンボル | TypeScript 日本語ハンドブック | js STUDIO

ただ、これだとAreaIdを定義する際にasを使わざるを得ず、少し雑になる

もしIDが何かしらのフォーマットに基づいていて精査できるのであれば型ガードでチェックしてから使うのがよい

例えば、あるID(ValidId)のフォーマットが「数字」と「言語コード」を組み合わせたもの(12345:ja)であるならば

const isValidId = (value: string): value is ValidId => {
   if (!value) false
   const [number, lang] = value.split(":")
    return !Number.isNaN(+number) && Object.prototype.hasOwnProperty.call(LANG_CODE, lang)
}

と精査できて、この条件式を通過した値はValidId型であると保証される