一,概述
为什么要学习TS?
- 就业 或 获得更大的竞争优势
- 获得更好的开发体验
- 解决JS中一些难以处理问题
JS语言的问题
使用了不存在的变量、函数或成员
把一个不确定的类型当作一个确定的类型处理
在使用null或undefined的成员
JS的原罪
js语言本身的特性,决定了该语言无法适应大型的复杂项目
弱类型:变量可以随时变化类型
解释性:错误发生的时候,是在运行时
TS语言的特点
TS是JS的超集,是一个可选的,静态的类型系统。
类型系统:对代码中所有的标识符(变量、函数、参数、返回值)进行类型检查。
可选的:学习曲线非常平滑
静态的:检查的时间点是在编译之前(tsc), TS不参与任何运行时的类型检查。
无论是浏览器环境,还是node环境,无法直接识别ts代码
tsc编译器: ts -> es
TS常识
2012年微软发布
二、在node中搭建ts开发环境
安装
全局安装:npm install -g typescript
默认情况下, TS会做出下面几种假设:
- 假设当前的执行环境是dom
- 如果代码中没有使用模块化语句(import,export),便认为该代码是全局执行
- 编译的目标代码的ES3
有两种方式可以更改以上假设:
- 使用tsc命名,加上选项参数
- 使用ts配置文件,更改编译选项
TS的配置文件
创建方式:
- 手动新建 tsconfig.json
- 命令行:tsc --init
使用了配置文件后,使用tsc进行编译时,不能跟上文件名,如果跟上文件名,则会忽略文件名。
第三方库
@types/node
安装: cnpm install -D @types/node (开发时才需要)
@types 是一个TS官方的类型库,其中包含了很多对js代码的类型描述。
使用第三方库来简化编译运行流程
ts-node: 将ts代码在内存中完成编译,同时完成运行。
安装:cnpm i -g ts-node (也可以仅安装在工程中)
运行:ts-node 编译入口文件 (ts-node src/index.ts)
nodemon: 用于检测文件的变化
安装:cnpm i -g nodemon
运行:nodemon --exec ts-node src/index.ts
可以在package.json中进配置脚本命令:
"scripts": {
"dev": "nodemon --watch src -e ts --exec ts-node src/index.ts"
}
npm run dev 即可达到效果
三、基本类型检查
# 类型约束和编译结果对比
## 如何进行类型约束?
仅需要在 变量、函数参数、函数返回值位置后加上 ``` :类型```
ts在很多场景中可以完成类型推导
any: 表示任意类型,对该类型,ts不进行类型检查
## 源代码和编译结果的差异
编译结果张没有类型约束信息
# 基本类型
number: 数字
string:字符串
boolean:布尔值
数组
两种书写方法:
let nums: number[]
let nums: Array<nunber>
以上两种效果一样,代表数字类型的数组
object: 对象
null 和 undefined
null和undefined是所有其他类型的子类型,它们可以赋值给其他类型
通过在ts配置文件中添加 ```strictNullChecks: true```可以获得更严格的空类型检查,null和undefined只能赋值给自身。
# 其他常用类型
联合类型: “或" (多种类型选其一)
void类型: 通常用于约束函数的返回值,表示无返回
never类型:通常用于约束函数的返回值,表示该函数永远不可能结束
字面量类型:使用一个值进行约束
元祖类型(tuple): 一个固定长度的数组,且数组每项类型确定
any类型:可以绕过类型检查
# 类型别名
对已知的类型定义名称
语法:type 声明
# 函数的相关约束
函数重载:在函数实现之前,对函数调用的多种情况进行声明。
可选参数:可以在某些参数名后加上问号,表示该参数可以不用传递。可选参数必须在参数列表的末尾。
四、扩展类型 - 枚举
# 字面量类型的问题
# 枚举的使用
# 扩展知识:枚举的位运算
针对数字枚举
五、 模块化
# 在TS中使用模块化
前端领域中的模块化标准
ES6、commonjs、amd、system...
TS中,导入和导出模块,统一使用ES6的模块标准。
# 编译结果中的模块化
(可配置):tsconfig.json -> module
TS中的模块化在编译结果中:
- 如果编译结果的模块化标准是ES6: 没有区别
- 如果编译结果的模块化标准是commomjs:导出的声明变成export的属性,默认导出(export default)会变成export的default属性。
# 解决默认导入的错误
# TS中书写commonjs模块化代码
# 模块解析
六、接口
# 接口的概念
和类型别名一样,接口,不出现在编译结果中。
扩展类型 - 接口
扩展类型: 类型别名、枚举、 接口、 类
TS中的接口:用于约束类、对象、函数的契约(标准)
# 接口使用
接口约束对象
接口约束函数
接口可以继承 (extends)
可以通过接口之间的继承,实现多种接口的组合
使用类型别名可以实现类似的组合效果,需要通过```&```,它叫做交叉类型
它们的区别:
子接口不能覆盖父接口的成员
交叉类型会把相同成员的类型进行交叉