本文介绍了带有泛型的文字脚本自定义限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在使用库时,我发现在使用泛型时,在我看来像是一个错误:
type R<A> = A extends Bottom ? A : A
type Bottom = { test: number }
const f = <A extends Bottom>(a: A) => {
useIt(a) // type error here
}
const useIt = <A extends Bottom>(a: R<A>) => console.log(a)
正如您在Playground example,由于某种不明原因,a
不能用作R<A>
,即使此类型等同于A
。
类型错误为:
Argument of type 'A' is not assignable to parameter of type 'R<A>'.
Type 'Bottom' is not assignable to type 'R<A>'.
使用具体类型而不是泛型将按预期工作,例如:
type X = {test: 1}
const x: R<X> = {test: 1} // all good
const noX: R<X> = {test: 2} // error
拥有更好的限制类型也会像预期的那样对具体类型起作用:
type R<A> = A extends Bottom ? A : never
const x: R<X> = {test: 1} // all good
const error: R<{}> = {} // type error as expected given that {} doesn't extend Bottom
那么,有什么方法可以让它与泛型一起工作吗?
推荐答案
这更多地是设计限制而不是错误;未解析的条件类型(依赖于尚未指定的泛型类型参数的类型)或多或少被编译器完全延迟,几乎没有任何内容被视为可分配给它们。
有一个未解决的问题,microsoft/TypeScript#23132,它建议使用泛型约束来确定对未解析的条件类型的赋值;我认为如果实现了这个建议,您的示例代码将会工作(因为
A extends Bottom
将被视为真)...因此,如果您认为这个问题比现有的更有说服力,那么您可能想要给它一个👍,并可能解释您的用例。还有microsoft/TypeScript#33912,它建议使用控制流分析来确定对未解析的条件类型的赋值,如果要实现它,这可能也会有所帮助。
目前,我认为"使其工作"的唯一方法是使用type assertions,如:
useIt(a as R<A>)
或表示您的类型,以便它不再是未解析的条件类型;在您的示例代码中,R<A>
是无条件的A
,因此
// type R<A> = A extends Bottom ? A : A
type R<A> = A
会解决这个问题。
实际上,我看到您将代码的另一部分中的R<A>
更改为实质上的Extract<A, Bottom>
。在某些情况下,Extract<T, U>
可以替换为交叉点T & U
而不会产生不良影响;您可以尝试这样做:// type R<A> = A extends Bottom ? A : never
type R<A> = A & Bottom
这也可能行得通。
好的,希望这会有帮助;祝你好运!
这篇关于带有泛型的文字脚本自定义限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!