本文介绍了带有泛型的文字脚本自定义限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用库时,我发现在使用泛型时,在我看来像是一个错误:

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

这也可能行得通。


好的,希望这会有帮助;祝你好运!

Link to code

这篇关于带有泛型的文字脚本自定义限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 23:49