TypeScipt 每日类型挑战-medium-<Last of Array>

128 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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]这种格式,就返回最后一个元素。

更多