即使在他的伟大着作basarat中对类型断言进行了TypeScript Deep Dive解释:
基本上,如果
S
是T
的子类型或S
是{{1}的子类型,则从T
到T
的断言会成功}}
我想知道类型注释S
和类型断言variable: type
之间的确切区别是什么,更确切地说,当类型断言工作与否时,尤其是关于TypeScript错误有时令人惊讶:看到它们expression as type
和foo3
变量如下:
foo5
我注意到的其他差异:在VSCode的interface Foo {
n?: number;
s: string;
}
const foo1 = {} as Foo; // ok
const foo2 = { n: 1 } as Foo; // ok
const foo3 = { n: '' } as Foo; // KO: "Property 's' is missing..."
const foo4 = { n: '' as any } as Foo; // ok
const foo5 = { n: 1, x: 2 } as Foo; // KO: "Property 's' is missing..."
const foo6 = { s: '', x: 2 } as Foo; // ok
const foo7 = { s: 1, x: 2 } as Foo; // KO: "Types of property 's' are incompatible."
接口中重命名n
属性不会传播到被断言的表达式,而是使用类型带注释的变量。
答案 0 :(得分:3)
我想知道类型注释之间的确切区别是什么
variable: type
并键入断言表达式为
类型声明variable: type
告诉编译器变量必须始终符合声明的类型。当为变量赋值(该值必须与声明的类型兼容)时,由typechecker使用它,并且每当使用变量时(变量的声明类型必须与变量的使用方式兼容)每个特定的地方)。
类型断言会覆盖内置类型兼容性规则。它允许您告诉编译器您知道该值实际上符合您在断言中提供的类型,从而抑制了有关类型不兼容的错误消息。但是有一些限制 - 你不能断言变量有你想要的任何类型(BTW只有any
类型)。正如您在问题中引用的那样,要使类型断言起作用,
如果S是T的子类型或T是S的子类型,则从S到T的断言成功
在每个例子中,它都以这种方式运作:
const foo3 = { n: '' } as Foo; // KO: "Property 's' is missing..."
这里有两种类型:{n?: number, s: string}
和{n: string}
检查兼容性 - 如果其中任何一种都可以转换为另一种。它无法以任何一种方式完成:在某种程度上,{n: string}
缺少非可选s
而n
的类型错误(必须为number | undefined
);另一方面,{n?: number, s: string}
的{{1}}类型错误(必须为n
)。
完整的错误消息是
string
在报告结构类型不兼容时,编译器只选择一个不兼容的属性显示在错误消息中 - 它可能是上面提到的三种不兼容性中的任何一种。
Type '{ n: string; }' cannot be converted to type 'Foo'.
Property 's' is missing in type '{ n: string; }'.
有效,因为const foo4 = { n: '' as any } as Foo; // ok
与{n?: number, s: string}
兼容:第一个可以分配给第二个 - {n: any}
与任何内容兼容,any
只是被忽略(基本上,如果某个值具有与声明类型兼容的所有非可选属性,则该值与该类型兼容)
s
const foo5 = { n: 1, x: 2 } as Foo; // KO: "Property 's' is missing..."
无法分配给{n: number, x: number}
- {n?: number, s: string}
缺失,正如编译器所说:
s
Type '{ n: number; x: number; }' cannot be converted to type 'Foo'.
Property 's' is missing in type '{ n: number; x: number; }'.
有效,因为const foo6 = { s: '', x: 2 } as Foo; // ok
可分配给{s: string, x: number}
:{n?: number, s: string}
没问题,缺少s
即可,因为它被声明为可选,额外{{1}被忽略
n
x
的类型不兼容:
const foo7 = { s: 1, x: 2 } as Foo; // KO: "Types of property 's' are incompatible."