即使在他的伟大著作TypeScript Deep Dive 中对类型断言进行了basarat解释:
基本上,如果是 的子类型或的子类型,则从 type
S
到的断言T
成功。S
T
T
S
我想知道 type annotationvariable: type
和 type assertion之间的确切区别是什么expression as type
,更准确地说,当类型断言是否有效时,尤其是关于 TypeScript 错误有时令人惊讶:请参阅下面的foo3
和foo5
变量:
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."
Run Code Online (Sandbox Code Playgroud)
我注意到的其他区别:在 VSCode 中重命名接口中的n
属性Foo
不会传播到被断言的表达式,而它正在处理类型注释的变量。
art*_*tem 11
我想知道类型注释
variable: type
和类型断言表达式作为类型之间的确切区别是什么
类型声明variable: type
告诉编译器变量必须始终符合声明的类型。类型检查器在为变量赋值时(该值必须与声明的类型兼容)以及在使用该变量时(变量的声明类型必须与变量的任何使用方式兼容)使用它每个特定的地方)。
类型断言覆盖内置的类型兼容性规则。它允许您告诉编译器您知道该值实际上符合您在断言中给出的类型,从而抑制有关类型不兼容的错误消息。但是,有限制 - 您不能仅仅断言变量具有您想要的任何类型(顺便说一句,有any
类型只是为了)。正如您在问题中引用的那样,要使类型断言起作用,
如果 S 是 T 的子类型或 T 是 S 的子类型,则从类型 S 到 T 的断言成功
在每个示例中,它都以这种方式工作:
const foo3 = { n: '' } as Foo; // KO: "Property 's' is missing..."
Run Code Online (Sandbox Code Playgroud)
这里有两种类型:{n?: number, s: string}
和{n: string}
检查兼容性 - 如果它们中的任何一个可以转换为另一个。无论哪种方式都不能完成:在一种方式中,{n: string}
缺少非可选s
并且n
类型错误(必须是number | undefined
);换句话说,(must be ) 的{n?: number, s: string}
类型错误。n
string
完整的错误信息是
Type '{ n: string; }' cannot be converted to type 'Foo'.
Property 's' is missing in type '{ n: string; }'.
Run Code Online (Sandbox Code Playgroud)
当报告结构类型不兼容时,编译器只选择一个不兼容属性显示在错误消息中 - 它可能是上述三种不兼容中的任何一种。
const foo4 = { n: '' as any } as Foo; // ok
Run Code Online (Sandbox Code Playgroud)
有效{n?: number, s: string}
是因为兼容{n: any}
:第一个可以分配给第二个 -any
与任何东西兼容,并且s
被忽略(基本上,如果一个值具有与声明类型兼容的所有非可选属性,则它与类型兼容)
const foo5 = { n: 1, x: 2 } as Foo; // KO: "Property 's' is missing..."
Run Code Online (Sandbox Code Playgroud)
{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; }'.
Run Code Online (Sandbox Code Playgroud)
const foo6 = { s: '', x: 2 } as Foo; // ok
Run Code Online (Sandbox Code Playgroud)
有效,因为{s: string, x: number}
可分配给{n?: number, s: string}
:s
是可以的,缺少n
是可以的,因为它被声明为可选,额外的x
被忽略
const foo7 = { s: 1, x: 2 } as Foo; // KO: "Types of property 's' are incompatible."
Run Code Online (Sandbox Code Playgroud)
类型s
不兼容:
Type '{ s: number; x: number; }' cannot be converted to type 'Foo'.
Types of property 's' are incompatible.
Type 'number' is not comparable to type 'string'.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1835 次 |
最近记录: |