TypeScript
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 编辑器打开话,也会明显的波浪线异常提示:
这得益于 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)。