一.背景
2010 – 微软团队开始开发
2012 – 第一个公开版本发布(TypeScript 0.8)
2013 – TypeScript 0.9 发布,支持泛型了
2014 – TypeScript 1.0 发布,Visual Studio 2013 默认支持 TypeScript 了。同时,源码从 CodePlex 迁移到 Github
2017 – TypeScript 2.1 发布
2018 – TypeScript 3.2 发布
TypeScript 最初是个微软内部项目,叫 Strada,致力于提升大型 JS 项目(当时内部需求是 Bing Maps、 Office Web Apps 甚至 Windows 8 apps)的可靠性和可维护性。2010 年开始开发,2012 年 10 月发布了第一个开源版本,持续迭代至今
二.目标
Application scale JavaScript development is hard.
JavaScript 最初设计目标是作为一种脚本语言,缺少一些构建大型应用必备的基础特性,如:
静态类型
结构化机制(类、模块、接口等)
类型上的缺陷导致很多错误要到运行时才能暴露出来,另一方面,缺少静态类型也是 JS 编辑体验差的主要原因,智能提示、自动补全等现代化编辑体验都是从 Visual Studio 开始的:
基于类型推断的智能提示
基于 JSDoc 的智能提示
基于 TypeScript 声明文件的智能提示
Application scale JavaScript development is hard, TypeScript makes it easier.
TypeScript 期望通过源码转译的方式填补这些缺陷,给 JavaScript 添上 OOP 支持(Class、Interface 等),以及可选的静态类型系统,在 ES5 时代(2010 年)建立起开发大型 JavaScript 应用的根基
此外,TypeScript 还给 JavaScript 带来了一个重要的东西,d.ts
声明文件:
Working with existing JavaScript libraries, declaration file can be written and maintained separately.
通过独立的声明文件让现有 JavaScript 类库也能拥有 TypeScript 的类型优势,在提升 JavaScript 编辑体验方面迈出了一大步
三.定位
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
有 3 个关键点:
typed:类型化的。给 JS 补充了(可选的)静态类型
superset of JavaScript:超集。兼容 JS,支持混用,现有的 JavaScript 类库可以直接使用
compiles to plain JavaScript:编译到原生 JS。从 JavaScript 开始,以 JavaScript 结束
具体的:
从 JavaScript 开始:超集意味着所有 JavaScript 代码都是 TypeScript,语法语义都与 JavaScript 一致,复制粘贴就可以开始了
提供可选的静态类型、类与模块:类型不仅让 JavaScript 开发能够使用高效的开发工具和实践(如静态检查和代码重构),而且不会带来运行时的性能损耗(静态类型仅在编译时存在)
以 JavaScript 结束:TypeScript 编译产生地道的原生 JavaScript,因此支持最前沿的 JavaScript 特性,并且能在任何支持 ES3+的宿主环境中运行
可以认为TypeScript 是 JavaScript 的语法糖:
TypeScript is a syntactic sugar for JavaScript. TypeScript syntax is a superset of ECMAScript 2015 (ES2015) syntax. Every JavaScript program is also a TypeScript program.
(摘自Introduction | TypeScript Language Specification)
像类型补丁一样,能与 JavaScript 世界完美融合,这才是 TypeScript 生命力之所在:
Starts and ends with JavaScript, and optional static types, classes, modules.
并且,这一点从 TypeScript 公开发布(2012 年末)至今(2019 年初)都没有变过
四.设计原则
追求:
静态识别出那些可能有错的部分
为大段代码提供结构化机制
不给编译产物增加运行时开销
输出整洁、地道、可读的 JavaScript 代码
实现一种可组合、易推理的(easy to reason about)语言
永远和 ES 规范保持一致
保留所有 JavaScript 代码的运行时行为
避免添加表达式级的语法特性
一致的、完全可擦除的结构化类型系统
成为跨平台开发工具
从 TypeScript 1.0 起不要引入重大破坏性变动
拒绝:
完全模仿现有语言的设计,应该以 JavaScript 的行为和开发者的意愿作为语言设计指南
优化程序的运行时性能,应该忠实输出原生 JavaScript 代码,而不刻意优化
完善的或“可证明正确的”类型系统,而应该在正确性和生产力之间取得平衡
提供一端到另一端的(封闭)构建管道,应该让系统具有可扩展性,让编译器适用于更复杂的构建工作流
添加或依赖运行时类型信息,或根据类型系统的结果很长不同的代码,应该鼓励不依赖运行时信息(run-time metadata)的编程模式
额外提供运行时功能或类库,应该用 TypeScript 来描述现有类库
引入可能会让用户感到意外的行为,应该适当考虑其他常用语言所采用的模式
五.特性
类型系统
是 JavaScript 类型的形式化:JavaScript 类型动态系统的静态表示
提供类型推断与结构化类型:实际上不必都给标注上类型(类型推断能够解决一部分)
能够配合现有 JavaScript 类库使用:声明文件可以独立编写维护
不是可证明的类型安全(provably type safe):类型只反映意图,并不提供保证
最重要的是,静态类型仅在编译时存在:
In the JavaScript output, all type annotations have been erased.
例如:
// TypeScript
function f(s: string) {
return s;
}
// 编译得到的JavaScript,类型标注统统擦掉
function f(s) {
return s;
}
另外,TypeScript 虽然提供了静态类型系统,并在编译时严格检查,但并不像Haskell 类型系统一样可证明,可推理。因此,TypeScript 类型系统更多地只是作为 JavaScript 的静态类型补丁,像注释一样体现“意图”,并不保证安全
甚至编译错误并不阻塞代码生成,类型检查报错只是提醒这里可能存在问题:
You can use TypeScript even if there are errors in your code. But in this case, TypeScript is warning that your code will likely not run as expected.
类与模块
可扩展的应用结构化机制:类、模块和接口支持定义组件间的明确联系
遵从最新标准:类、模块和箭头函数语法都与 ES6 标准一致
也支持业界主流模块系统:如 CommonJS 和 AMD 模块
注意,模块的语法规则与 ES 标准一致,但在加载机制上存在差异,具体见Module Resolution
六.生态
(开源)编译器:typescript
工具:IDE 支持(VS、VSCode、Sublime、WebStorm、Vim 等)、Playground
类型库:DefinitelyTyped
样板项目:Samples、Community Samples
案例:GitHub TypeScript 项目(包括 Angular、ant-design 等)
参考资料
Anders Hejlsberg: Introducing TypeScript:TypeScript 公开发布演讲
TypeScript:上面演讲对应的 PPT