TypeScript Exclude<UnionOfTypes, Interface> 是类型 "never"
TypeScript Exclude<UnionOfTypes, Interface> is type "never"
为什么下面的代码中 Exclude<A,B>
解析为 never
类型?打字稿编译器不能(通过静态分析)知道 A
和 B
扩展 Parent
因此 Exclude<Choices, Parent>
应该解析为类型 C
?
interface Parent {}
interface A extends Parent {}
interface B extends Parent {}
interface C {}
type Choices = A | B | C
type Test = Exclude<Choices, Parent> // = type "never"???
const c: C = {}
const d: Test = c // Type 'C' is not assignable to type 'never'
我可以硬编码 Parent = A | B
但我不确定为什么需要这样做。
这是因为 TypeScript 有 duck typing。具体来说,由于 C
和 Parent
是相同的接口,因此 C
可分配给 Parent
.
具体来说,这个编译:
const c: C = {};
const p: Parent = c;
所以,尽管 C
没有明确地 extend Parent
,TypeScript 仍然说 C
是 Parent
.
如果您希望它起作用,只需向 Parent
添加 C
没有的内容即可。
interface Parent { foo: string }
interface A extends Parent {}
interface B extends Parent {}
interface C {}
type Choices = A | B | C
type Test = Exclude<Choices, Parent> // = type C
const c: C = {}
const d: Test = c // works!
我创建了一个文字工具如下
// It is the opposite operation to [exclude].
type Has<T, U> = U extends T ? U : never;
用法如下
type A = {
a : number;
aa:number;
aaa:number;
}
type B = {
b : number;
}
type C = {
c : number;
}
type D = {
d : number;
}
// Here means the type A
type Node_HasA = Has<{
a : number;
}, A|B|C|D>
为什么下面的代码中 Exclude<A,B>
解析为 never
类型?打字稿编译器不能(通过静态分析)知道 A
和 B
扩展 Parent
因此 Exclude<Choices, Parent>
应该解析为类型 C
?
interface Parent {}
interface A extends Parent {}
interface B extends Parent {}
interface C {}
type Choices = A | B | C
type Test = Exclude<Choices, Parent> // = type "never"???
const c: C = {}
const d: Test = c // Type 'C' is not assignable to type 'never'
我可以硬编码 Parent = A | B
但我不确定为什么需要这样做。
这是因为 TypeScript 有 duck typing。具体来说,由于 C
和 Parent
是相同的接口,因此 C
可分配给 Parent
.
具体来说,这个编译:
const c: C = {};
const p: Parent = c;
所以,尽管 C
没有明确地 extend Parent
,TypeScript 仍然说 C
是 Parent
.
如果您希望它起作用,只需向 Parent
添加 C
没有的内容即可。
interface Parent { foo: string }
interface A extends Parent {}
interface B extends Parent {}
interface C {}
type Choices = A | B | C
type Test = Exclude<Choices, Parent> // = type C
const c: C = {}
const d: Test = c // works!
我创建了一个文字工具如下
// It is the opposite operation to [exclude].
type Has<T, U> = U extends T ? U : never;
用法如下
type A = {
a : number;
aa:number;
aaa:number;
}
type B = {
b : number;
}
type C = {
c : number;
}
type D = {
d : number;
}
// Here means the type A
type Node_HasA = Has<{
a : number;
}, A|B|C|D>