持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情
题目
实现一个通用Last<T>,它接受一个数组T并返回其最后一个元素的类型。
例如
type arr1 = ['a', 'b', 'c']
type arr2 = [3, 2, 1]
type tail1 = Last<arr1> // expected to be 'c'
type tail2 = Last<arr2> // expected to be 1
解答
Last类型的实现这里介绍两种方法,都比较巧妙,一开始可能想不到,但是看过之后其实很容易理解,一种方式是利用索引,另外一种方式是使用infer推导占位的方式实现,之前的文章中也有关于infer关键字的用法的详细解析。
解法一:索引方式
代码详解:
type Last<T extends any[]> = [any, ...T][T['length']]
本身T的长度是T['length'], 前面加上一个any,再利用...解构T,那么新数组[any, ...T]的第T['length']个元素即是数组T的最后一个元素的类型。
可以用以下伪代码辅助理解:
// 原数组
const T = [1, 2, 3]
// 新数组
const arr = [any, 1, 2, 3]
// 结果: 3
const result = arr[T['length']]
T['length']:表示原始T数组的长度,例如[1, 2, 3],长度值为3。而在新数组中,索引为3的位置正好是最后一个元素的索引。
解法二:infer占位推导
代码详解:
type Last<T extends any[]> = T extends [...infer R, infer L] ? L : never
- 使用
T extends any[]对T进行类型约束,T必须是一个数组,具体内容是啥我们不关心 - 使用
L对原数组中最后一个元素进行占位,而其它元素我们用一个R数组表示。 - 再用
extends条件语句进行判断,如果数组满足[...infer R, infer L]这种格式,就返回最后一个元素。