跳到主要内容

TypeScript

官方文档:https://www.typescriptlang.org/zh/

TypeScript 是一个开源的编程语言,通过在 JavaScript(世界上最常用的语言之一) 的基础上添加静态类型定义构建而成。简称 TS。

类型提供了一种描述对象形状的方法。可以帮助提供更好的文档,还可以让 TypeScript 验证你的代码可以正常工作。

在 TypeScript 中,不是每个地方都需要标注类型,因为类型推断允许您无需编写额外的代码即可获得大量功能。TypeScript 的类型推导意味着只有您希望获得更佳的安全性时,才需要在您的代码中写更多的类型注释。

所有有效的 JavaScript 代码同时也是有效的 TypeScript 代码。你也许会有类型检查的错误,但是这不会阻止你运行生成的 JavaScript。

相关文件

  • 正式文件是用 .ts 后缀,react 的话是 .tsx
  • 声明文件是用 .d.ts 后缀,可选
  • 跟配置有关的文件是 tsconfig.json

类型推论

如果没有明确的指定类型,那么 TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。

以下代码虽然没有指定类型,但是会在编译的时候报错:

let myFavoriteNumber = "seven";
myFavoriteNumber = 7;

// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

事实上,它等价于:

let myFavoriteNumber: string = "seven";
myFavoriteNumber = 7;

// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

TypeScript 会在没有明确的指定类型的时候推测出一个类型,这就是类型推论。

如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查:

let myFavoriteNumber;
myFavoriteNumber = "seven";
myFavoriteNumber = 7;

为什么要用 TS

从 TypeScript 的名字就可以看出来,「类型」是其最核心的特性。

我们知道,JavaScript 是一门非常灵活的编程语言:

  • 它没有类型约束,一个变量可能初始化时是字符串,过一会儿又被赋值为数字。
  • 由于隐式类型转换的存在,有的变量的类型很难在运行前就确定。
  • 基于原型的面向对象编程,使得原型上的属性或方法可以在运行时被修改。
  • 函数是 JavaScript 中的一等公民,可以赋值给变量,也可以当作参数或返回值。

这种灵活性就像一把双刃剑,一方面使得 JavaScript 蓬勃发展,无所不能,从 2013 年开始就一直蝉联最普遍使用的编程语言排行榜冠军;另一方面也使得它的代码质量参次不起,维护成本高,运行时错误多。

JavaScript 是一门解释型语言,开发过程中没有编译阶段,它是动态类型,有些错误无法在开发的时候暴露出来,编辑器也不会报错。例如:

let foo = 1;
foo.split(" ");
// Uncaught TypeError: foo.split is not a function
// 运行时会报错(foo.split 不是一个函数),造成线上 bug

TypeScript 是静态类型,改用 TypeScript 后,因为 TypeScript 在运行前需要先编译为 JavaScript,而在编译阶段就会进行类型检查,这段 TypeScript 代码在编译阶段就会报错了:

let foo = 1;
foo.split(" ");
// Property 'split' does not exist on type 'number'.
// 编译时会报错(数字没有 split 方法),无法通过编译

而且用 vscode 编辑器打开话,也会明显的波浪线异常提示:

1453-hZ7EyM

这得益于 TypeScript 强大的类型推论,即使不去手动声明变量 foo 的类型,也能在变量初始化时自动推论出它是一个 number 类型。

这个就是使用 TS 的好处之一。

还有一个很明显的好处就是:TypeScript 增强了编辑器(IDE)的功能,包括代码补全、接口提示、跳转到定义、代码重构等,这在很大程度上提高了开发效率。

弱类型

TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性,所以它们都是弱类型。

适用于任何规模

TypeScript 非常适用于大型项目或者安全性要求较高的后端项目——这是显而易见的,类型系统可以为大型项目带来更高的可维护性,以及更少的 bug。

TypeScript 还可以和 JavaScript 共存。这意味着如果你有一个使用 JavaScript 开发的旧项目,又想使用 TypeScript 的特性,那么你不需要急着把整个项目都迁移到 TypeScript,你可以使用 TypeScript 编写新文件,然后在后续更迭中逐步迁移旧文件。如果一些 JavaScript 文件的迁移成本太高,TypeScript 也提供了一个方案,可以让你在不修改 JavaScript 文件的前提下,编写一个类型声明文件,实现旧项目的渐进式迁移。

与标准同步发展

TypeScript 的另一个重要的特性就是坚持与 ECMAScript 标准同步发展。

ECMAScript 是 JavaScript 核心语法的标准,自 2015 年起,每年都会发布一个新版本,包含一些新的语法。

一个新的语法从提案到变成正式标准,需要经历以下几个阶段:

  • Stage 0:展示阶段,仅仅是提出了讨论、想法,尚未正式提案。
  • Stage 1:征求意见阶段,提供抽象的 API 描述,讨论可行性,关键算法等。
  • Stage 2:草案阶段,使用正式的规范语言精确描述其语法和语义。
  • Stage 3:候选人阶段,语法的设计工作已完成,需要浏览器、Node.js 等环境支持,搜集用户的反馈。
  • Stage 4:定案阶段,已准备好将其添加到正式的 ECMAScript 标准中。

一个语法进入到 Stage 3 阶段后,TypeScript 就会实现它。一方面,让我们可以尽早的使用到最新的语法,帮助它进入到下一个阶段;另一方面,处于 Stage 3 阶段的语法已经比较稳定了,基本不会有语法的变更,这使得我们能够放心的使用它。

总结

什么是 TypeScript?

  • TypeScript 是添加了类型系统的 JavaScript,适用于任何规模的项目(越大型项目越是推荐)。
  • TypeScript 是一门静态类型、弱类型的语言。
  • TypeScript 是完全兼容 JavaScript 的,它不会修改 JavaScript 运行时的特性。
  • TypeScript 可以编译为 JavaScript,然后运行在浏览器、Node.js 等任何能运行 JavaScript 的环境中。
  • TypeScript 拥有很多编译选项,类型检查的严格程度由你决定。
  • TypeScript 可以和 JavaScript 共存,这意味着 JavaScript 项目能够渐进式的迁移到 TypeScript。
  • TypeScript 增强了编辑器(IDE)的功能,提供了代码补全、接口提示、跳转到定义、代码重构等能力。
  • TypeScript 拥有活跃的社区,大多数常用的第三方库都提供了类型声明。
  • TypeScript 与标准同步发展,符合最新的 ECMAScript 标准(stage 3)。

开源书籍推荐