gpt4 book ai didi

typescript - 如何测试两种类型是否完全相同

转载 作者:行者123 更新时间:2023-12-04 11:20:54 26 4
gpt4 key购买 nike

这是我的第一次尝试:( playground link )

/** Trigger a compiler error when a value is _not_ an exact type. */
declare const exactType: <T, U extends T>(
draft?: U,
expected?: T
) => T extends U ? T : 1 & 0

declare let a: any[]
declare let b: [number][]

// $ExpectError
exactType(a, b)

相关: https://github.com/gcanti/typelevel-ts/issues/39

最佳答案

啊,type-level equality operator . @MattMcCutchen 提出了一个 solution涉及通用条件类型,它可以很好地检测两种类型何时完全相等,而不是只能相互分配。在一个完美的类型系统中,“相互可分配”和“相等”可能是一回事,但 TypeScript 并不是完美的。特别是 any type 既可分配给任何其他类型,也可从任何其他类型分配,这意味着 string extends any ? true : falseany extends string ? true: false两者都评估为 true ,尽管stringany不是同一类型。

这是一个 IfEquals<T, U, Y, N>计算结果为 Y 的类型如果 TU相等,且 N除此以外。

type IfEquals<T, U, Y=unknown, N=never> =
(<G>() => G extends T ? 1 : 2) extends
(<G>() => G extends U ? 1 : 2) ? Y : N;

让我们看看它的工作原理:
type EQ = IfEquals<any[], [number][], "same", "different">; // "different"

好的,这些被识别为不同的类型。可能还有其他一些边缘情况,您认为相同的两种类型被视为不同,反之亦然:
type EQ1 = IfEquals<
{ a: string } & { b: number },
{ a: string, b: number },
"same", "different">; // "different"!

type EQ2 = IfEquals<
{ (): string, (x: string): number },
{ (x: string): number, (): string },
"same", "different">; // "different", as expected, but:

type EQ3 = IfEquals<
{ (): string } & { (x: string): number },
{ (x: string): number } & { (): string },
"same", "different">; // "same"!! but they are not the same,
// intersections of functions are order-dependent

无论如何,给定这种类型,我们可以创建一个生成错误的函数,除非这两种类型以这种方式相等:
/** Trigger a compiler error when a value is _not_ an exact type. */
declare const exactType: <T, U>(
draft: T & IfEquals<T, U>,
expected: U & IfEquals<T, U>
) => IfEquals<T, U>

declare let a: any[]
declare let b: [number][]

// $ExpectError
exactType(a, b) // error

每个参数都有一个类型 TU (用于泛型参数的类型推断)与 IfEquals<T, U> 相交除非 T 否则会出现错误和 U是平等的。我想,这给出了你想要的行为。

请注意,此函数的参数不是可选的。我真的不知道你为什么希望它们是可选的,但是(至少在打开 --strictNullChecks 的情况下)它削弱了这样做的检查:
declare let c: string | undefined
declare let d: string
exactType(c, d) // no error if optional parameters!

这取决于你是否重要。

无论如何希望有帮助。祝你好运!

关于typescript - 如何测试两种类型是否完全相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53807517/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com