一、why ! 为何要选择Typescript
Javascript 灵活、动态的特性让它活跃在编程语言一线,但动态类型又让他显的很神秘,Javascript 中的变量类型只有在代码运行的时候才能被编译器知道,这就有可能给代码增加了隐含的bug。其次,对于程序员来讲,动态类型代码不能够直接的描述自身,代码毕竟是写给人看的,只是偶尔让计算机执行一下,对吧。
当项目的规模越来越大,参与开发的人员越来越多,代码越来越臃肿,代码如何描述自身就越显得越重要。举个例子,当代码封装了通用的组件或者通用的函数时,如何产出一个一目了然的文档?靠人工维护,手写文档明显不现实。这里涉及到几个问题:
- 接口和函数如何描述自己的参数和返回值?
- 接口和函数的参数和返回值在需求的多次迭代之后发生了很多变化,这个说明文档如何更新?
- 数据格式如何定义描述?
在日益复杂的 web 应用中缺少一个很重要的东西:静态类型。因为有了静态类型,我们才能知道函数需要什么样的参数,并且返回的参数是什么样,哪些参数是可以不传或者参数需要的格式是什么样。知道了这些,我们就可以不需要在使用其他人写的函数时还需要研究函数内部的实现,并且将一些可能由于类型而产生的bug 提前规避掉。
- TypeScript 增加了代码的可读性和可维护性
- 类型系统实际上是最好的文档
- 可以在编译阶段就发现大部分错误,这总比在运行时候出错好
- 增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等
- Typescript 十分宽容,即便没有显示的定义类型,它也有类型推论
- Typescript 可以定义从简单到复杂的一切类型
- TypeScript 拥有活跃的社区,大部分第三方库都有提供给 TypeScript 的类型定义文件
- Google的Angular 2 及其后续版本以及白鹭游戏引擎等就是使用 Typescript 编写的
- TypeScript 拥抱了 ES6 规范,也支持部分 ES7 草案的规范
虽然对于熟悉了灵活的 Javascript 的前端开发同学来说,学习Typescript 需要一定成本,毕竟需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等面向对象语言的特性,但Typescript 这么多优点怎能错过,何况前端开发已经脱离了刀耕火种的时代,大型的复杂web应用已是无法阻挡的趋势。
二、what ! 什么是Typescript
TypeScript 简称 TS,是 JavaScript 的超集,它由微软开发,主要提供了类型系统和对 ES6 的支持,TypeScript 最终编译为JavaScript。
举两个个例子窥探一下Typescript 的静态类型。
定义变量:
// 数值类型变量
let decNum : number = 12
// 字符串类型变量
let myName : string = 'song jun bo'
// 布尔值类型
let isDone: boolean = false;
以上的变量均定义了类型,此时若赋值了和自身不同类型的值,编译器会报错。
定义函数:
function describeType(name:string, left = 10,right:any, url:string|Object ,width:number,height?:number):string| number{
}
以上的函数包含信息包括:
- 参数 name 参数的类型为字符串,传数值等其他非字符串类型时编译器会报错
- 参数 left 的默认值为10
- 参数 right 是任意类型,可以传递任意类型
- 参数 url 的类型可以为字符串类型或者对象类型,此时传其他类型的值会报错
- 参数 height 为可选参数,可不传
- 这个函数的返回值类型可以是字符串类型或者 number 类型
三、how ! Typescript 如何安装使用
安装:
npm install -g typescript
编译:
tsc index.ts
typescript 文件以 .ts 为后缀
ts的文件编译完之后会生成 js 文件
下面的例子看一下 Typescript 编译为 Javascript 之后是怎么样的。
typescript 代码:
// index.ts 文件
// 数值类型
let myNumber : number = 12;
// 字符串类型
let name : string = 'song jun bo';
// 布尔值类型
let done: boolean = false;
// 联合类型
let typeUnion : string | number ;
// 数值类型数组
let numTypeArr : number[] = [1,2,3];
// 枚举
enum direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
// 接口
interface addFuncInteface{
(x:number,y:number):number
}
let value : addFuncInteface = (left:number,right:number)=>{ return left + right }
// 泛型
function createArray(length: number, value: T): Array {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
编译之后的 Javescript 代码
// 数值类型
var myNumber = 12;
// 字符串类型
var name = 'song jun bo';
// 布尔值类型
var done = false;
// 联合类型
var typeUnion;
// 数值类型数组
var numTypeArr = [1, 2, 3];
// 枚举
var direction;
(function (direction) {
direction["Up"] = "UP";
direction["Down"] = "DOWN";
direction["Left"] = "LEFT";
direction["Right"] = "RIGHT";
})(direction || (direction = {}));
var value = function (left, right) { return left + right; };
// 泛型
function createArray(length, value) {
var result = [];
for (var i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
通过编译前后代码的对比,我们不难发现,Typescript 可以看成是穿上类型检查机制外衣的Javascript,本质上还是Javascript。
编译方式:
- 直接调用 tsc,编译器会从当前目录开始去查找 tsconfig.json 文件,逐级向上搜索父目录。
- 调用 tsc -p,可以指定一个包含 tsconfig.json文件的目录进行编译。如果没有找到 tsconfig.json 文件,TypeScript 会编译每个文件并在对应文件的同级目录产出。
- 调用 tsc ./dataType/index.ts 可以指定编译 dataType 文件夹中的 index.ts 文件并且在同级目录下输出编译后的js 文件。
编辑器选哪个?
主流的编辑器都支持 TypeScript,推荐使用 Visual Studio Code,它内置了 TypeScript 支持,它本身也是Typescript 编写的,对Typescript有最纯天然的支持。
Typescript 和 ES6、ES5 是什么关系,下面这个图可以很好的说明:
Typescript 一直在努力与 ECMAScript 的标准规范和提案对齐,因此在typescript 中可以使用新的语言特性,比如decorators 装饰器、async/await 异步 等。
babel 是将高级版本的 JavaScript 编译为目标版本的 JavaScript。比如将es6 编译为es5, TypeScript 是将 TypeScript 编译为目标版本的 JavaScript。它们的编译是重叠的,也就是说 TypeScript 可以不再依赖 babel 编译。