问题
如何推断泛型类的泛型需求(扩展部分中的内容)?
解释
// UserGivenClassThatCouldHaveAnyGeneric
class A<T extends string> {
constructor(a: T) {}
}我如何推断泛型T必须扩展string。我需要有条件的陈述中的这些信息。
我试过以下几种方法
type E<W> = any extends A<infer T> ? W extends T ? A<W> : void : void当给定E不扩展T所需的内容时,W应该是无效的,但是当它扩展时,它应该是A。但是,这根本不起作用,尽管没有显示语法错误警告。
发布于 2020-04-09 01:15:41
我的建议是将E<W>改为如下所示:
type E<W> = never extends A<infer T> ? [W] extends [T] ? A<W> : void : never首先,检查类型为any的条件类型,与any extends X ? Y : Z一样,最终将被计算为大多数类型X的联合Y | Z。也就是说,any是特殊的大小写,可以接受条件类型的两个分支。有关这方面的一些讨论,请参见微软/打字稿#27418。假设您只是尝试使用条件类型的真正分支,那么最好使用never extends X ? Y : Z。通常,never extends X将始终为真,然后结果将是Y。此外,如果有一种类型的人你不想担心你的工会混乱,你应该把它变成never,而不是void。类型A | never的计算结果为A,而A | void一般不计算。
因此,让我们将type E<W> = any extends A<infer T> ? W extends T ? A<W> : void : void改为type E<W> = never extends A<infer T> ? W extends T ? A<W> : void : never。
现在剩下的问题是:当W本身是一个联合类型时,您想做什么?如果您离开用W extends T而不是[W] extends [T]定义的W extends T,那么它将被视为条件类型。这意味着,如果W是一个类似于A | B | C的联合类型,那么E<W>将为该联盟的每个成员计算条件,并将结果结合起来,生成相当于E<A> | E<B> | E<C>的结果。也许这就是你想要的,但可能不是。毕竟,如果W是string | number,那么您可能希望void出来,而不是A<string> | void,对吗?
条件类型何时变得分布式的规则是,您正在检查“裸”或“裸”泛型类型参数。由于W是泛型类型参数,条件类型W extends T ? ...将是分布式的。关闭这种行为的最简单的方法是“为”类型参数加上某种协变量,比如单元素元组类型。所以它变成了[W] extends [T] ? ...。
好吧,希望这能帮上忙,祝你好运!
https://stackoverflow.com/questions/61108283
复制相似问题