静态类型检查

静态类型系统描述了程序运行时值的结构和行为。

像 TypeScript 这样的静态类型检查器会利用类型系统提供的信息,并在事态发展不对劲的时候告知我们。

const message = "hello!";
 
message();

// This expression is not callable.
// Type 'String' has no call signatures.

用 TypeScript 运行上一个例子,它会在我们执行代码之前首先抛出一个错误。

非异常失败

目前为止,我们讨论的都是运行时错误 —— JavaScript 运行时告诉我们,它觉得某个地方有异常。

这些异常之所以能够抛出,是因为 ECMAScript 规范 明确规定了针对异常应该表现的行为。

举个例子,规范指出,试图调用无法调用的东西应该抛出一个错误。

也许这听上去像是“显而易见的行为”,并且你会觉得,访问对象上不存在的属性时,也会抛出一个错误。

但恰恰相反,JavaScript 的表现和我们的预想不同,它返回的是值 undefined

const user = {
    name: 'Daniel',
    age: 26,
};
user.location;       // 返回 undefined

最终,我们需要一个静态类型系统来告诉我们,哪些代码在这个系统中被标记为错误的代码 —— 即使它是不会马上引起错误的“有效” JavaScript 代码。

在 TypeScript 中,下面的代码会抛出一个错误,指出 location 没有定义:

const user = {
  name: "Daniel",
  age: 26,
};
 
user.location;
//Property 'location' does not exist on type '{ name: string; age: number; }'.

虽然有时候这意味着你需要在表达的内容上进行权衡,但我们的目的是为了找到程序中更多合法的 bug。

而 TypeScript 也的确可以捕获到很多合法的 bug:

举个例子,拼写错误:

const announcement = "Hello World!";
 
// 你需要花多久才能注意到拼写错误?
announcement.toLocaleLowercase();
announcement.toLocalLowerCase();
 
// 实际上正确的拼写是这样的……
announcement.toLocaleLowerCase();

未调用的函数