将 any 与 void 进行比较时,为什么类型是联合?
When comparing any to void why is the type a union?
我想检查提供的类型是否为 void
并且惊讶地发现在传入 any
时返回了一个联合。有人可以解释这是为什么吗?
type test<T> = T extends void ? void extends T ? 1 : 0 : 0;
type v1 = test<any>; // 1 | 0
type v2 = test<unknown>; // 0
type v3 = test<undefined>; // 0
type v4 = test<null>; // 0
type v5 = test<never>; // never
type v6 = test<void>; // 1
type v7 = test<boolean>; // 0
type v8 = test<string>; // 0
type v9 = test<number>; // 0
type v10 = test<'void'>; // 0
type v11 = test<{}>; // 0
查看真假分支的 microsoft/TypeScript#40049 for an authoritative answer. When any
is checked via a conditional type, the result will be the union。这可能令人惊讶,但它正在按预期工作。
相关评论:
This isn't especially well-documented outside of the source-code, but in the checker you'll find in the relevant place:
// Return union of trueType and falseType for 'any' since it matches anything
if (checkType.flags & TypeFlags.Any) {
So any
is treated like a wildcard that matches both branches.
我想我理解了这一点:
void extends any ? 1 : 0
解析为 1
,意思是 void 确实扩展了 any。我想这是 Typescript 作者的设计决定,我找不到原因。根据我的测试 - 所有类型都扩展 any
(用 {}, () => 1, "v", 3, unknown
检查)。
然后,any extends void ? 1 : 0
解析为 1 | 0
,这实际上是有意义的(它将是条件类型中的两种类型之一)。
结果
==> test<any>
=== any extends void ? void extends any ? 1 : 0 : 0
=== any extends void ? 1 : 0
=== 1 | 0
我想检查提供的类型是否为 void
并且惊讶地发现在传入 any
时返回了一个联合。有人可以解释这是为什么吗?
type test<T> = T extends void ? void extends T ? 1 : 0 : 0;
type v1 = test<any>; // 1 | 0
type v2 = test<unknown>; // 0
type v3 = test<undefined>; // 0
type v4 = test<null>; // 0
type v5 = test<never>; // never
type v6 = test<void>; // 1
type v7 = test<boolean>; // 0
type v8 = test<string>; // 0
type v9 = test<number>; // 0
type v10 = test<'void'>; // 0
type v11 = test<{}>; // 0
查看真假分支的 microsoft/TypeScript#40049 for an authoritative answer. When any
is checked via a conditional type, the result will be the union。这可能令人惊讶,但它正在按预期工作。
相关评论:
This isn't especially well-documented outside of the source-code, but in the checker you'll find in the relevant place:
// Return union of trueType and falseType for 'any' since it matches anything if (checkType.flags & TypeFlags.Any) {
So
any
is treated like a wildcard that matches both branches.
我想我理解了这一点:
void extends any ? 1 : 0
解析为 1
,意思是 void 确实扩展了 any。我想这是 Typescript 作者的设计决定,我找不到原因。根据我的测试 - 所有类型都扩展 any
(用 {}, () => 1, "v", 3, unknown
检查)。
然后,any extends void ? 1 : 0
解析为 1 | 0
,这实际上是有意义的(它将是条件类型中的两种类型之一)。
结果
==> test<any>
=== any extends void ? void extends any ? 1 : 0 : 0
=== any extends void ? 1 : 0
=== 1 | 0