Open
Description
题目
题目链接:FirstOfArray
实现一个 FirstOfArray
满足测试用例 cases
,作用是返回数组中的第一项
- 测试用例1:
[3, 2, 1]
结果为3
- 测试用例2:
[() => 123, { a: string }]
结果为() => 123
- 测试用例3:
[]
结果为never
- 测试用例4:
[undefined]
结果为undefined
import { Equal, Expect } from "@type-challenges/utils";
type cases = [
Expect<Equal<FirstOfArray<[3, 2, 1]>, 3>>,
Expect<Equal<FirstOfArray<[() => 123, { a: string }]>, () => 123>>,
Expect<Equal<FirstOfArray<[]>, never>>,
Expect<Equal<FirstOfArray<[undefined]>, undefined>>
];
type errors = [
// @ts-expect-error
FirstOfArray<"notArray">,
// @ts-expect-error
FirstOfArray<{ 0: "arrayLike" }>
];
答案
方法一
type FirstOfArray<Arr extends any[]> =
Arr extends [infer Item, ...any[]] ? Item : never;
知识点
- 泛型
Arr
继承自任意类型的数组 infer Item
是声明一个Item
,类似于变量声明,在后面都可以使用[infer Item, ...any[]]
取出数组的第一项,放在变量Item
- 通过
extends
判断泛型Arr
是否继承自[infer Item, ...any[]]
- 空数组
[] extends [infer Item, ...any[]]
结果为false
,所以输出为never
- 其余情况为
true
,输出数组第一项
- 通过
方法二
type FirstOfArray<Arr extends any[]> = Arr extends [] ? never : Arr[0];
知识点
[] extens []
为true
输出为never
- 其余情况为
false
输出为Arr[0]
方法三
type FirstOfArray<Arr extends any[]> = "0" extends keyof Arr ? Arr[0] : never;
知识点
keyof Arr
取出数组中的每一个key
"0" extends keyof Arr
判断数组中有没第一项,因为空数组是没有第一项的。- 如果有第一项,输出
Arr[0]
否则为never
方法四
type FirstOfArray<Arr extends any[]> = Arr["length"] extends 0 ? never : Arr[0];
知识点
Arr["length"]
可以获取泛型Arr
的长度Arr["length"] extends 0
判断数组长度是否为0
- 如果为
0
输出never
,否者输出Arr[0]
方法五
type FirstOrArray<Arr extends any[]> =
Arr[number] extends never ? never : Arr[0];
知识点
-
Arr[number]
可以得到数组的每一项值的联合类型type A1<Arr> = Arr[number] type A2: A1<[1, 2, 3]> // => 1 | 2 | 3 type A3: A1<[]> // => never
-
如果是个空数组
Arr<[]>
会返回never
,通过判断Arr[number] extends never
是否为never
-
如果为
never
输出never
否则输出Arr[0]
方法六
type FirstOfArray<Arr extends any[]> = Arr[Extract<keyof Arr, "0">];
总结
空数组的几种判断方法
T extends []
T extends never[]
"0" extends keyof T
T["length"] extends 0
T[number] extends never