TypeScript介绍
官方声明
JavaScript that scales。TypeScript is a typed superset of JavaScript that compiles to plain JavaScript
特点
- 出自Anders Hejlsberg之手(C#,Delphi作者)
- 兼容ES规范,同时也有自己的一些规范(如namespace)
- 自带编译器,也是TS写的
- 语言即服务(IDE,第三方库的方法声明等)
静态分析
输入错误
interface ISort {
name: string,
age: number
}
function sortByName(a: ISort[]) {
var result = a.slice(0);
result.sort((x, y) => {
return x.name.localCompare(y.name);
});
return result;
}
执行tsc
编译:
error TS2339: Property 'localCompare' does not exist on type 'string'.
localCompare这种输入手误在没有智能提示的情况下是较为常见的,如果这个函数是原生JS,那会等到运行时才会报错。如果使用支持TS的IDE,则输入localCompare后会直接标红,避免运行时这块代码被执行到然后报错再Debug。
非空判断
function countLines(text?: string[]): number {
let count = 0;
for (const line of text) {
if (line && line.length !== 0) {
count = count + 1;
}
}
return count;
}
执行tsc
编译:
error TS2532: Object is possibly 'undefined'.
可以看到for (const line of text) {
这行中的text变量是有可能为undefined的(?:
是TS语法,表示存在不存在都有可能)。这种缺少非空判断到时的JS运行时错误在工作中也是容易出现的。
访问权限
class Person {
protected name: string;
public age: number;
constructor(name: string) { this.name = name; }
}
class Employee extends Person {
static someAttr = 1;
private department: string;
constructor(name: string, department: string) {
super(name);
this.department = department;
}
}
let howard = new Employee("Howard", "Sales");
console.log(howard.name);
执行tsc
编译:
error TS2445: Property 'name' is protected and only accessible within class 'Person' and its subclasses.
Person中name属性是protected类型,只能在自己类中或者子类中使用,这和Java是一样的。
interface Machine {
move(): void
}
interface Human {
run(): void
}
class Robot implements Machine, Human {
run() {
console.log('run');
}
}
执行tsc
编译:
error TS2420: Class 'Robot' incorrectly implements interface 'Machine'.
Property 'move' is missing in type 'Robot'.
Robot类实现多个接口时,必须实现每个接口的所有抽象方法,这也是实现多继承的一种方法。
扩展性
TS适合大规模JS应用,正如他的官方宣传语JavaScript that scales
。
- 类型系统+静态分析+智能感知/提示,使大规模的应用代码质量更高,更好维护。
- 有类似VSCode这样配套的IDE支持,方便的查看引用关系,并进行重构,再也不用全局搜索,一个个修改了。
- 数据结构(应用配置、前后端接口等JSON格式数据)的类型校验,和强类型的后端配合更为无缝、健壮,方便后期前后端整体迭代、重构。
超集
由于兼容ES规范,所以可以比较方便的升级现有的JS代码,逐渐的加类型注解。渐进式(容我盗个词)增强代码健壮性。不过这个也是理论上的,我目前维护的一个项目有比较重的历史包袱,模块管理是CommonJS/ES6 Modules混杂的,我尝试将编译系统从Babel完全迁移到TS,折腾后并没有成功(Babel还是很强大的= =)。
对于历史包袱比较多的老项目,不建议完全替换Babel,但是可以曲线引入TS,用TS编译到ES6,再用Babel来编译到ES5。
代码运行时质量
大型前端应用如何兼顾开发迭代&持续交付
的速度和线上运行时
的的质量,近期思考后认为很重要的一点就是增强应用数据结构或者说是结构化数据(配置、前后端后接口等JSON格式数据)的稳定性、健壮性。引入强类型系统,增加编译期检查,减少运行时错误,可以显著的改善这个点。很多问题可以在编码时发现,而不是出现运行时错误时再Debug。
和Babel、Flow的对比
- TypeScript 是推荐套餐,Babel 系列是自助餐。
- TypeScript自带编译器,包含ES最新规范,还有自己的Features和类型校验;Flow是一个类型校验工具。在类型校验这块两者目前已经相差不大。
- Babel、Flow是Facebook在推,TypeScript是Microsoft在推,都有不错的生态,但我个人感觉Flow目前还不够成熟(听说FB最近招了一些Lisp大牛来做这个事,没有考证过),TS出自一位大牛(C#、Delphi作者)之手,目前生态发展的非常好,社区口碑也很不错,感觉更靠谱些(并不是说Flow不靠谱)。
开发效率
- IDE智能提示/纠错,对于迭代、重构、减少Bug提升代码质量会有帮助,同时也可以提升开发效率。
提示:
校验:
只要安装了@types/lodash这个模块,VSCode中输入_可以智能提示所有方法。目前主流的JS模块都有声明模块。如果是内部开发的模块,可以自己声明定义文件,团队内部都可以公用这个定义文件,提升整体开发效率。可以用tsc --declaration myFile.ts
快速生成声明定义文件。
配置
运行tsc -init
可以快速生成工程的TS配置文件tsconfig.json
,默认的三个选项是分别是:
-
"target":"es5"
: 编译后的逻辑代码的ES版本,还有es3,es2105等选项。 -
"module":"commonjs"
:编译后的模块化组织的代码,还有amd,umd,es2015等选项。 -
"strict":true
:严格校验,包含不能有没意义的any,null校验等选项。
链接
社区反馈
https://slack.engineering/typescript-at-slack-a81307fa288d
https://blog.asana.com/2014/11/asana-switching-typescript/
https://medium.com/@clayallsopp/incrementally-migrating-javascript-to-typescript-565020e49c88
https://insights.stackoverflow.com/survey/2017#technology-most-loved-dreaded-and-wanted-languages
基于TS的知名开源项目
https://github.com/desktop/desktop
https://github.com/driftyco/ionic
https://github.com/Microsoft/vscode
https://github.com/ant-design/ant-design
https://github.com/mobxjs/mobx
https://github.com/cyclejs/cyclejs
https://github.com/palantir/blueprint
https://github.com/tastejs/todomvc/tree/gh-pages/examples/typescript-react
TS+React
https://github.com/Microsoft/TypeScript-React-Starter
https://github.com/Microsoft/TypeScript-React-Conversion-Guide
作者视频
https://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript
https://channel9.msdn.com/Events/Build/2017/B8088?ocid=player
和Babel、Flow的对比
https://www.zhihu.com/question/34867499
https://djcordhose.github.io/flow-vs-typescript/2016_hhjs.html#/8