🎯 题目描述
获取数组类型的第一个元素,假设我们有一个数组,比如
const fruits = ['苹果', '香蕉', '橙子']
现在我们要写一个类型,能够获取数组的第一个元素的类型。就像这样:
type FirstFruit = First<['苹果', '香蕉', '橙子']> // 结果应该是 苹果
type EmptyResult = First<[]> // 如果是空数组,结果应该是:never
简单来说就是:
- 如果给一个数组
['苹果', '香蕉', '橙子'],就要得到苹果这个类型。 - 如果给我一个空数组
[],要得到never类型。 - 数组里可以放任何类型的元素。
💡 题解
方案一:最简单直接的方式
type First<T extends any[]> = T extends [] ? never : T[0]
🔍 代码解析
T extends any[]限制T必须是数组类型T extends []判断数组是否为空数组- 三元表达式:空数组返回
never,否则返回T[0]
🎯 测试一下
type First<T extends any[]> = T extends [] ? never : T[0]
type Test1 = First<['1', '2']> // '1'
type Test2 = First<[() => 123, { a: string }]> // () => 123
type Test3 = First<[]> // never
type Test4 = First<[undefined]> // undefined
方案二:使用infer(类型推断)
type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never
🔍 代码解析
infer F表示推断第一个元素的类型...any[]表示剩余的元素可以是任意类型- 如果能够解构成功,返回推断出的
F类型 - 否则返回
never
🎯 测试一下
type First<T> = T extends [infer F, ...any[]] ? F : never
type Test1 = First<['1', '2']> // '1'
type Test2 = First<[() => 123, { a: string }]> // () => 123
type Test3 = First<[]> // never
type Test4 = First<[undefined]> // undefined
🌟 进阶思考
可以尝试实现类似的类型:
- Last:获取数组最后一个元素
- Tail:获取除第一个元素外的所有元素
- Init:获取除最后一个元素外的所有元素