此问题已在此处有答案:
How to test if two types are exactly the same(7个回答)
3天前关闭。
- 在搜索如何在TypeScript中测试类型相等时,我发现了这个SO question,它的标题看起来很有前途,但它的实际问题不是关于类型相等的测试。*
我想要的东西,可以测试两种类型的等效性:
type IsEqual<Type1, Type2> = ???;
例如,它可以用来确定重载函数的返回类型:
type IsAmbiguous<T> = T extends { isString: infer K } ? IsEqual<K,boolean> extends true ? T : never : never;
function doThing(val: number, opts: { isString: true }): string;
function doThing(val: number, opts: { isString: false }): number;
function doThing<T>(val: number, opts: IsAmbiguous<T>): string | number;
前两个重载函数根据传入选项的窄类型预测返回类型。然而,在第三重载函数中,opts
可以通过变量传递,在这种情况下,isString
的类型是布尔型的,并且返回类型将在运行时由doThing
实现确定,但在编译时不能(或可能不)被TypeScript编译器知道。
IsEqual的执行情况如何?
1条答案
按热度按时间ryevplcw1#
回答我自己的问题。
测试类型相等的关键是使用交集(
&
)和并集(|
)运算符。我们测试两个类型的联合是否扩展了两个类型的交集。在TypeScript(和JavaScript)中,subtype extends supertype
意味着subtype
是更具体的类型,supertype
是更一般的类型。对于对象和类,这通常意味着向派生类型添加属性或方法。对于标量类型,这意味着子类型是一个特定的值(3.14 extends number
)。在这里,
IsEqual
采用更通用的类型(union),并测试它是否扩展了更窄的类型(intersection)。如果它确实扩展了,那么这两个类型必须相等,因为任何一个类型都没有添加任何额外的内容。如果引入了一些额外的类型,则超类型将比子类型更窄,因此无法扩展。下面是一些狭义和广义延伸的例子。
下面是一个包含
IsEqual
实现的TS Playground及其使用示例。在准备这个Q&A时,我发现this medium article和this SO answer非常有帮助。