例えば
type Dogs = Array<{name: string, age: number}>
みたいな既存型がある時に
{name: string, age: number}
この部分を得たいという事が稀によくあります。
type Dog = {name: string, age: number}
type Dogs = Array<Dog>
最初からDogを定義しておいて、そのDogを元にDogsを作っていれば良かったじゃん?と言われるとそれはそうなんですが、外からやってくる型(例えばGraphQLから生成されたPick<Dog, 'name' | 'age'>
みたいなアドホックな型定義だとか)の場合はそうも言ってられません。
そういう時にはinfer(conditional types)を使ってArray<T>
のT
部分をキャプチャして得る事ができます。
type Flatten<T> = T extends Array<infer U> ? U : never
type Dog = Flatten<Dogs>
この例ではArrayを引っ剥がしましたが、Arrayと同様にPromiseだとかMaybe(type Maybe<T> = T | null
)だとかを引っ剥がすのにも使えたり、ビルトインのユーティリティ型であるReturnTypeの定義なんかにも使われています。