TypeScript是JavaScript的一个超集,主要提供了类型系统和对ES6的支持,它有Microsoft开发,代码开源在github上。
引用官方的定义: TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.Any browser. Any host. Any OS. Open source.
翻译成中文即是: TypeScript是JavaScript的类型的超集,它可以编译成纯JavaScript。编译出来的JavaScript可以运行在任何浏览器上。TypeScript编译工具可以运行在任何服务器和操作系统上。TypeScript是开源的。
为什么选择TypeScript
这里总结一下其优势:
TypeScript增加了代码的可读性和可维护性
- 类型系统实际上是最好的文档,大部分函数看看类型的定义就可以知道如何使用了
- 可以在编译阶段就发现大部分错误,这总比在运行是出错好
- 增强了编辑器和IDE的功能,包括代码补全、接口提示、跳转到定义、重构等
TypeScript非常包容
- TypeScript是JavaScript的超集,
.js
文件可以直接明明为.ts
即可 - 即使不显式的定义类型,也能够自动做出类型推断
- 可以定义从简单到复杂的一切类型
- 即使TypeSript编译报错,也可以生成JavaScript文件
- 兼容第三方库,即使第三方库不是用TypeScript写的,也可以编写单独的类型
TypeScript拥有活跃的社区
- 大部分第三方库都提供给TypeScript的类型定义文件
- Google开发的Angular2就是使用TypeScript编写的
- ES6的一部分特性是借鉴的TypeScript的
- TypeScript拥抱了ES6规范,也支持部分ES7草案的规范
也说些缺点:
- 有一定的学习成本,需要理解接口(interfaces)、泛型(generics)、类(classes)、枚举类型(enums)等前端工程师可能不是很熟悉的东西。而且中文资源不多
- 短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript能够减少其维护成本
- 集成到构建流程需要一些工作量
- 可能和一些库结合的不是很完美
总之可以根据自己团队和项目的情况判断是否需要使用TypeScript。
安装TypeScript请自行百度
Hello TypeScript
我们从一个简答的例子开始。将以下代码复制到 hello.ts
中:
然后执行
这是后会生成一个编译好的文件
上述例子中,我们用 : 指定 person 参数类型为 string 。但是编译为 js 之
后,并没有什么检查的代码被插入进来。
TypeScript只会进行静态检查,如果发现有错误,编译的时候会报错。
下面尝试吧这段代码编译一下:
编辑器中会提示错误,编译的时候也会出错:
index.ts(6,36): error TS2345: Argument of type ‘number[]’ is not assignable to parameter of type ‘string’.
但是还是生成了 js
文件:
TypeScript编译的时候即使报错了,还是会生成编译结果,我们仍然可以使用这个编译后的文件
如果要在报错的时候终止 js 文件的生成,可以在 tsconfig.json 中配置 noEmitOnError 即可。关于 tsconfig.json ,请参阅官方手册(中文版)。
原始数据类型
JavaScript的类型分为两种:原始数据类型和对象类型。
原始数据类型包括:布尔值、数值、字符串、null、undefined、以及ES6中的新类型Symbol
本节主要介绍前五种原始数据类型在TypeScript中的应用。
布尔值
布尔值是最基础的数据类型,在TypeScript中,使用 boolean
定义布尔值类型:
注意,使用构造函数 Boolean 创建的对象不是布尔值:
事实上 new Boolean()
返回的是一个 Boolean
对象,应该这样定义它的类型:
直接调用 Boolean
可以返回一个 boolean
类型:
在TypeScript中,boolean是JavaScript中的基本类型,而Boolean是JavaScript中的构造函数。其他基本类型(除了null和undefined)一样,不在赘述。
数值
使用 number
定义数值类型:
编译结果为:
其中 0b1010 和 0o744 是 ES6 中的二进制和八进制表示法,它们会被编译为十进制数字。ES5中的语法不会被转换。
字符串
使用 string
定义字符串:
编译结果:
空值
JavaScript中没有空值的概念,在TypeScript中,可以用 void
表示没有任何返回值的函数:
使用 void
声明一个变量没什么用处,因为你只能把它赋值为 null
或 undefined
。
Null 和 Undefined
在 TypeScrip 中可以使用 null
和 undefined
来定义这两个原始数据类型:
undefined类型的变量只能被赋值为 undefined
,null类型的变量只能被赋值为 null
。
与 void 类型的区别是 undefined 和 null 是所有类型的子类,也就是说 undefined 类型的变量可以赋值给 number/string… 类型的变量:
而 void 类型的变量不能赋值给 number 类型的变量:
任意值
任意值(any) 来表示允许赋值为任意类型
什么是任意值类型?
如果是普通类型,在赋值过程中改变其类型是不被允许的:
而如果是 any 类型,则允许被赋值为任意类型:
未声明类型的变量
未声明类型的变量会被识别为 any 类型:
相当于:
类型推断
在 2.1 版本之后,增加了 类型推断
这一概念。如果没有明确指定类型,TypeScript会按照类型推断的规则来推断出一个类型。
以下代码没有指定类型,编译时会报错:
在TypeScript 2.1 之前,如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查。TypeScript 2.1 中,编译器会考虑对 myFavoriteNumber 的最后一次赋值来检查类型。
联合类型
联合类型表示取值可以为多种类型中的一种。举个例子:
如果这样写就会报错:
联合类型使用 |
分割每个类型。这里 string | number
的含义是允许 myFavoriteNumber 的类型时 string 或 number 而不能时其他类型。
访问联合类型的属性和方法
当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法:
因为 length
不是 number 和 string 的共有属性,所以会报错。访问 toString()
就没有问题:
联合类型的变量在赋值时也会根据类型推断的规则推断出一个类型:
上例,在第二行 myFavoriteNumber 被推断为 string,访问其 length 属性不会报错,而第四行 myFavoriteNumber 被推断为 number,访问其 length 属性就报错了。