やりたいこと
このような配列から
const samples = [
{
name: 'shiraishi',
age: 30
},
{
name: 'shiraishi'
}
]
このような型を作りたい。
type User = {
name: string
age?: number
}
解決方法
下記のように配列の要素の型を取り出す型ユーティリティ関数を定義します。
type Unwrap<Ary extends any[]> = Ary extends (infer R)[] ? R : never
この関数を適用した結果が以下です。
type User = Unwrap<typeof samples>
const test1: User = {
name: 'name',
age: 12
}
// エラー
const test2: User = {
name: 'name',
age: 'age' // Type 'string' is not assignable to type 'number'.(2322)
}
const test3: User = {
name: 'name',
}
const test4: User = {
name: 'name',
age: undefined
}
背景
API 側のアプリケーションから自動生成されるレスポンスのサンプルの json からフロントエンドの型を自動生成しようとしたのが始まりです。
しかし、一つのサンプルだけでは optional かどうかが分からなかったため、下記のような複数のサンプルを含んだ json を作成し、そこから型ユーティリティ関数を用いて型を作る方法を考えました。
[
{
"name": "shiraishi",
"age": 30
},
{
"name": "shiraishi"
}
]
関連
この問題を解決する方法として、特定パターンの key をオプショナルにする方法も考えました。