了解错误
每当 TypeScript 发现错误时,它都会尝试尽可能详细地解释问题所在。 因为它的类型系统是结构化的,所以这通常意味着对它发现问题的位置提供一些冗长的描述。
术语
您会经常在错误消息中看到一些有助于理解的术语。
可分配
TypeScript 认为一种类型可分配给另一种类型,前提是一种类型可以接受另一种类型的替代。
换句话说,Cat
可分配给 Animal
因为 Cat
是 Animal
的可接受替代品。 顾名思义,此关系用于通过检查“t”和“s”的类型来检查赋值“t = s;”的有效性。 它还用于检查两种类型相互作用的大多数其他地方。 例如,调用函数时,每个参数的类型必须可分配给参数的声明类型。
通俗地说,如果您看到T is not assignable to S
,您可以将其视为 TypeScript 说“T
和 S
不兼容”。 但是,请注意这是一个定向的关系:S
可分配给 T
并不意味着 T
可分配给 S
。
例子
让我们看一些示例错误消息并了解发生了什么。
错误说明
每个错误都以一条前导消息开头,有时后面跟着更多的子消息。 您可以将每条子消息视为对“为什么?”的回答。 关于它上面的消息的问题。 让我们通过一些例子来看看它们在实践中是如何工作的。
下面是一个生成比示例本身更长的错误消息的示例:
ts
// @errors: 2322
let a: { m: number[] };
let b = { m: [""] };
a = b;
// @errors: 2322
let a: { m: number[] };
let b = { m: [""] };
a = b;
TypeScript 在检查最后一行时发现错误。 它发出错误的逻辑遵循其确定分配是否正确的逻辑:
b
的类型可以分配给a
吗? 没有为什么?- 因为 m 属性的类型不兼容。 为什么?
- 因为
b
的m
属性(string[]
)不可分配给a
的m
属性(number[]
)。 为什么? - 因为一个数组的元素类型(
string
)不能分配给另一个(number
)
额外属性
ts
// @errors: 2322
type A = { m: number };
const a: A = { m: 10, n: "" };
// @errors: 2322
type A = { m: number };
const a: A = { m: 10, n: "" };
联合操作
ts
// @errors: 2322
type Thing = "none" | { name: string };
const a: Thing = { name: 0 };
// @errors: 2322
type Thing = "none" | { name: string };
const a: Thing = { name: 0 };