在TypeScript中有没有办法子集化一个元组并获取ith and (i - 1)th元素?

也就是说,类似于:

type A = [string, number, symbol, boolean];
type B<T extends any[], U extends keyof T> = [T[U - 1], T[U]] // Here T[U - 1] is not valid TS ofc;

type C = B<A, 2> // [number, symbol];

推荐答案

这里不需要递归的最简单方法是认识到对于元组T,T的第U-1个元素与[undefined, ...T]的第U个元素相同,使用variadic tuple typeundefined添加到元组T的前面.undefined的用法有些主观;我之所以 Select 它,是因为一般说来,arr[-1]等于undefined.但这取决于您的用例,应该做什么才是正确的.

从概念上讲,你会想要写

type B<T extends any[], U extends keyof T> =
    [[undefined, ...T][U], T[U]];

但是类型判断器不理解U绝对是泛型T的索引[undefined, ...T].它不能执行更高阶的推理,即"较长的元组拥有较短元组的所有索引".因此,我们必须说服它以某种方式允许索引.一种方法是引入conditional判断,如果已知存在密钥,该判断将执行索引:

type Idx<T, K> = K extends keyof T ? T[K] : never;

这会给你带来:

type B<T extends any[], U extends keyof T> =
    [Idx<[undefined, ...T], U>, T[U]];

让我们来测试一下:

type A = [string, number, symbol, boolean];
type C = B<A, 2> // [number, symbol];
type Q = B<A, 0> // [undefined, string]
type R = B<A, 100>; // [undefined, undefined]

看起来不错 同样,这取决于您的用例,当索引超出边界或在边缘时,您希望看到什么.但希望你能调整它以满足你的需要.

Playground link to code

Typescript相关问答推荐

了解TS类型参数列表中的分配

TypeScript:在作为参数传递给另一个函数的记录中对函数的参数实现类型约束

无法正确推断嵌套泛型?

TypeScrip:逐个 case Select 退出noUncheck kedIndexedAccess

打字类型保护递归判断

CDK从可选的Lambda角色属性承担角色/复合主体中没有非空断言

为什么在leetcode问题的测试用例中,即使我确实得到了比预期更好的解决方案,这段代码也失败了?

如何编写在返回函数上分配了属性的类型安全泛型闭包

为什么&Quot;元素隐式具有';Any';类型,因为...即使我已经打字了,也不能作为索引显示错误吗?

在组件卸载时try 使用useEffect清除状态时发生冲突.react +打字

try 使Angular依赖注入工作

为什么特定的字符串不符合包括该字符串的枚举?

打字错误TS2305:模块常量没有导出的成员

为什么我的函数arg得到类型为Never?

对于VUE3,错误XX不存在于从不存在的类型上意味着什么?

typescript如何从映射类型推断

Typescript泛型验证指定了keyof的所有键

定义一个只允许来自另一个类型的特定字符串文字的类型的最佳方式

我可以使用对象属性的名称作为对象中的字符串值吗?

当并非所有歧视值都已知时,如何缩小受歧视联盟的范围?