TypeScript で 都道府県型を定義する
1. はじめに
カラダノートの 堀内 です。 前回 は電話番号型を定義してので、今回は都道府県を実装してみます。
2. ゴール
都道府県型を使って何を実現したいかというと、例えば、北海道と沖縄だけを対象とする処理を実装するときに、それ以外の都道府県だと型チェックでエラーを出したい、ということを目指します。
以下のようなイメージです。
ちなみに Prefecture<N>
の Nは 都道府県コード に相当します。
const hokkaido = Prefecture.from(1) // Prefecture<1> const okinawa = Prefecture.from(47) // Prefecture<47> const saitama = Prefecture.from(11) // Prefecture<11> // 北海道と沖縄のみを対象とする処理 const sendTo = (prefecture: Prefecture<1> | Prefecture<47>): void => { // do something ... } sendTo(hokkaido) sendTo(okinawa) sendTo(saitama) // ここを型チェックでエラーを出したい
3. 実装
もういきなりですが以下のとおり実装しました。
/* prefecture.ts */ // 都道府県コード一覧 const PREFECTURE_CODES = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 ] as const // 都道府県名一覧 const PREFECTURE_NAMES = [ '北海道', '青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県', '茨城県', '栃木県', '群馬県', '埼玉県', '千葉県', '東京都', '神奈川県', '新潟県', '富山県', '石川県', '福井県', '山梨県', '長野県', '岐阜県', '静岡県', '愛知県', '三重県', '滋賀県', '京都府', '大阪府', '兵庫県', '奈良県', '和歌山県', '鳥取県', '島根県', '岡山県', '広島県', '山口県', '徳島県', '香川県', '愛媛県', '高知県', '福岡県', '佐賀県', '長崎県', '熊本県', '大分県', '宮崎県', '鹿児島県', '沖縄県' ] as const // 都道府県コードのUnion型 export type PrefectureCode = typeof PREFECTURE_CODES[number] // 都道府県名のUnion型 export type PrefectureName = typeof PREFECTURE_NAMES[number] // 都道府県コードの検証 const validate = (value: PrefectureCode): boolean => { return PREFECTURE_CODES.includes(value) } // 都道府県型 export type Prefecture<Code extends PrefectureCode> = { readonly code: Code readonly name: PrefectureName } // 都道府県型の生成 export const Prefecture = { from<T extends PrefectureCode>(value: T): Prefecture<T> { if (!validate(value)) { throw new Error(`${value}は都道府県コードではありません`) } return { code: value, name: PREFECTURE_NAMES[value - 1] } } } export default Prefecture
で、ゴールのところでで書いたコードで動きを確認してみると、埼玉が型チェックでエラーになっています。
ドメイン知識をこんな感じで型定義にどんどん集めていきたい。 的なドメイン駆動設計をやりたい方をカラダノートでは募集しております。