TypeScript

时间:2017-12-27 15:47:33

标签: typescript

即使在他的伟大着作basarat中对类型断言进行了TypeScript Deep Dive解释:

  

基本上,如果ST的子类型或S是{{1}的子类型,则从TT的断言会成功}}

我想知道类型注释S和类型断言variable: type之间的确切区别是什么,更确切地说,当类型断言工作与否时,尤其是关于TypeScript错误有时令人惊讶:看到它们expression as typefoo3变量如下:

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属性不会传播到被断言的表达式,而是使用类型带注释的变量。

1 个答案:

答案 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}缺少非可选sn的类型错误(必须为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."