【问题标题】:How to use generic rest element with tuple types?如何使用具有元组类型的通用休息元素?
【发布时间】:2019-04-20 18:02:13
【问题描述】:

TypeScript 给我一个通用元组休息元素的错误

type Tuple<Value extends any[]> = [...Value];

错误:

$ tsc
src/index.ts:1:36 - error TS2574: A rest element type must be an array type.

1 type Tuple<Value extends any[]> = [...Value];

我在这里错过了什么?

  • 打字稿版本:typescript@3.1.6

type Tuple<HEAD, TAIL extends any[]> = [HEAD, ...TAIL];

没用,虽然这样可行:

type Tuple<Value extends any[]> = [...any[]];

【问题讨论】:

  • 你想在这里完成什么? [...Value]Value 有何不同?
  • 我试图制作一个 Head 和 Tail 泛型类型,但它们都不工作,所以这应该工作才能让其余的工作,我会更新我想要的完成
  • 您不能在类型上使用扩展运算符。
  • 为什么?,它在这里工作function tuple&lt;T extends any[]&gt;(...arg: T) {}
  • @DenisFrezzato 类型 [string, ...number[]] 有效。

标签: typescript variadic-tuple-types


【解决方案1】:

更新 TS4.0+。 TypeScript 4.0 引入了对variadic tuple types 的支持,因此这个问题中的代码应该可以按照编写的方式运行,而无需根据函数参数重新编写您的操作。万岁!


TS3.9- 答案:

您唯一缺少的是isn't currently supported 这样的推断。也许它会出现在 TypeScript 的未来版本中。幸运的是,仍然有一种方法可以通过在 function parameters 上用一个来表达所需的操作来做你想做的事,因为从 TypeScript 3.0 开始,有一种方法可以在元组/数组类型和函数参数之间进行转换,你可以使用infer 根据需要在参数类型上。

这是Tail 的一种可能实现:

type Tail<T extends any[]> = 
  ((...t: T) => void) extends ((x: any, ...u: infer U) => void) ? U : never;

type TestTail = Tail<[1,2,3,4]>; // [2,3,4]

请注意,您将元组/数组类型 T 传播到参数列表中,然后将第一个参数之后的所有内容推断为另一个元组/数组休息类型。

同样,您可以以我称之为Cons 的方式实现您的Tuple

type Cons<H, T extends any[]> = 
  ((h: H, ...t: T) => void) extends ((...u: infer U) => void) ? U : never;

type TestCons = Cons<string, [number, boolean]>; // [string, number, boolean]

我会将Head 留给你作为练习(当人们想要看起来聪明而不是懒惰时,他们会这么说)。

无论如何,希望这可以帮助您取得进步。祝你好运!

【讨论】:

  • 谢谢,我想我可以做类似type Tuple&lt;Head, Tail extends any[]&gt; = [Head, ...Tail]; type Head&lt;T&gt; = T extends Tuple&lt;infer H, any[]&gt; ? H : never; type Tail&lt;T&gt; = T extends Tuple&lt;any, R&gt; ? R : never; 的事情,但是哦,好吧
猜你喜欢
  • 2019-01-15
  • 2019-07-12
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 1970-01-01
相关资源
最近更新 更多