【问题标题】:How to write a generic type with constraint extending iterable with Typescript如何使用 Typescript 编写具有可迭代约束的泛型类型
【发布时间】:2020-01-23 11:43:53
【问题描述】:

我正在尝试写这种类型:

type Pagination<I extends Iterable> = Readonly<{
  seek: number;
  limit: number;
  total: number;
  items: I;
}>;

这样用户就可以使用了:

Pagination<Map<number, any>>

但这似乎不起作用,因为Iterable 还需要一个泛型参数。

所以我只剩下了

type Pagination<I> = Readonly<{
  seek: number;
  limit: number;
  total: number;
  items: Iterable<I>;
}>;

虽然这也有效,但类型签名现在变为Pagination&lt;number&gt;,无法进一步限制应该使用哪种可迭代对象。

【问题讨论】:

  • 你可以做到type Pagination&lt;I extends Iterable&lt;any&gt;&gt; = Readonly&lt;{ /*...*/ items: I }&gt;
  • @TitianCernicova-Dragomir 这就是答案!请为此提交答案。

标签: typescript typescript-generics


【解决方案1】:

您可以使用可迭代本身的泛型参数而不是项目类型,T extends Iterable&lt;any&gt;

type Pagination<I extends Iterable<any>> = Readonly<{
  seek: number;
  limit: number;
  total: number;
  items: I;
}>;

注意:如果您出于某种原因需要项目类型,您可以使用条件类型来提取它:

type Pagination<I extends Iterable<any>> = Readonly<{
  seek: number;
  limit: number;
  total: number;
  items: I;
  current: I extends Iterable<infer Item> ? Item: never
}>;

declare let map: Pagination<Map<string, number>>
map.current // [string, number]

declare let arr: Pagination<string[]>
arr.current // string

Play

【讨论】:

  • current 表现得像具体化类型吗?在那个值不能存在,所以它只是用来帮助参数化其他需要内部项类型的函数吗?
  • @CMCDragonkai 不确定我是否理解您的评论。当前项目的类型没有相对于T 定义,所以如果TIterable(这将是由于其他约束),我们将得到可迭代的Item。这确实可以帮助参数化需要项目类型的其他函数
猜你喜欢
  • 2018-03-05
  • 1970-01-01
  • 2011-06-23
  • 2016-03-21
  • 1970-01-01
  • 2019-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多