細かすぎて伝わらないタイトル
問題
例えば以下のような場合、onClickの引数にはvalueが取りうる'0' | '1' | '2'
に縛りたい。
const numberDict = [
{value: '0', label: 'ゼロ'},
{value: '1', label: 'ワン'},
{value: '2', label: 'ツー'},
]
const onClick = (newValue: '0' | '1' | '2') => { // 引数の型を動的に指定したい
setLabel(newValue)
}
onClick(numberDict[0].value);
解決
type NumberDictValues = Pick<typeof numberDict[number], 'value'>['value']
const onClick = (
newValue: NumberDictValues
) => {
onClick(newValue)
}
詳細
考え方を順を追って説明します。
変数の型を導き出す。
まずはnumberDict
の型を導出するため、typeof
を使います。
numberDict
はas const
でwideningを阻止します。
numberDict = {/* 略 */} as const
typeof numberDict
配列を展開する
配列の展開をします。
numberDict[number]
という書き方をすると、インデックスアクセスで得られる値の型を出せます。
typeof numberDict[number]
オブジェクトの値を抜き出す
最後にオブジェクトから値だけを抜き出します。
{}['key']
という書き方でkey
でアクセスできる値をユニオン型で取得できます。
typeof numberDict[number]['value']