問題
配列`T`を受け取り、その最初のプロパティの型を返す`First<T>`を実装します。
例えば:
```ts
type arr1 = ['a', 'b', 'c']
type arr2 = [3, 2, 1]
type head1 = First<arr1> // expected to be 'a'
type head2 = First<arr2> // expected to be 3
type cases = [
Expect<Equal<First<[3, 2, 1]>, 3>>,
Expect<Equal<First<[() => 123, { a: string }]>, () => 123>>,
Expect<Equal<First<[]>, never>>,
Expect<Equal<First<[undefined]>, undefined>>,
]
```
配列型を受け取り、最初の要素の型を返す型を実装する問題です。
回答
type First<T extends any[]> = T extends [infer A, ...infer rest] ? A : never
実は最初思いついたのは以下の回答だったのですが、他の方が挙げていた上の回答がとても綺麗だったのでこちらを回答として解説していきたいと思います。(下記の回答でも一応テストは通過できます)
type First<T extends any[]> = T extends [] ? never : T[0]
解説
-
infer
inferは一言で説明するのが難しいのですが、extends
の右辺に置くことができる、型を推論する演算子です。
今回のinfer A
というのは、Tを[A, ...]
というAを最初の要素にした配列型と推論できればA
を、できなければnever
を返すという書き方です。
なんでこのinfer
を使った解き方が優れているのかというと、これ最初の要素の型以外もすごく楽に指定できるんですよね。
type Last<T extends any[]> = T extends [...infer rest, infer A] ? A : never
こうすると最後の要素を指定できますし、
type Second<T extends any[]> = T extends [unknown, infer A, ...infer rest] ? A : never
こうすれば二番目の要素、みたいな感じで色々なパターンを同じ方法で解けます。すごい。
リンク