一、TypeScript 介绍?
- TypeScript (简称 TS) 是 JavaScript 的超集(js 有的 ts 都有,并且为 js 添加了类型系统、接口、枚举等)。
- ts 相比于 js 的优势:
- 类型化思维方式:使得开发更加严谨,提前发现错误,减少改 bug 的时间;
- 类型系统提高了代码的可读性,并使维护和重构代码更加容易;
- 补充了接口,枚举等开发大型应用时 js 缺失的功能。
二、安装解析 TS 的工具包
-
node.js / 浏览器,只认识 js 代码,不认识 ts 代码,所以需要先将 ts 代码转化为 js 代码,然后就可以在 node.js / 浏览器中运行了。
-
安装工具包:
# 打开终端,输入命令安装包 $ npm install -g typescript # 生成 ts 配置文件 $ tsc -init # 运行命令将 ts 文件转换成 js 文件 $ tsc index.ts # OR 实时监听 $ tsc --watch index.ts # 执行 ts 文件的步骤: 先转换成 js, 在执行 js 文件 # 1. tsc index.ts # 2. node index.js
-
简化执行 ts 文件步骤
- 安装 ts-node 包 (这个包在内部会先将 ts 文件转换成 js,然后再执行 js 代码)
$ npm install -g ts-node # 执行文件: $ ts-node index.ts
-
设置 VScode 自动编译 ts 文件
1. 在对应终端运行:tsc --init ,创建 tsconfig.js 文件
2. 修改 tsconfig.js 文件,设置编译后的输入 js 文件目录:"outDor": "./js/"
3. 终端设置 vscode 监视任务,之后修改项目中的 ts 会自动生成 js文件
三、TS 基础知识
ts 中的类型注解:是一种为变量添加类型约定的方式
注意:约定了什么类型,就只能给变量赋什么类型的值
-
定义 number 类型
let num: number = 10
-
定义字符串类型
let str: string = 'abcd'
-
定义布尔类型
let bool: boolean = true
-
定义 undefined 和 null 类型
let u: undefined = undefined let u2: undefined let n: null = null
-
定义函数
// 对 形参 和 返回值 加上类型注解 function fn(x: number, y: number): number { return x + y } function fn2(x: number, y?: number): number { // 可选参数 return x + y } function fn3(x: number, y: number, ...arr: any[]): number { // 不确定参数 return x + y } // 使用变量接受函数的返回值 // 注意:正常来说形参和实参数量必须相等,除非特定 let num: number = fn(1, 2)
-
定义数组(通常是相同类型的数据)
let arr1: string[] = ['ab', 'cd'] let arr2: number[] = new Array(1, 2, 3) // 遍历数组 for (let i: number = 0; i < arr1.length; i++) { console.log(arr1[i]) }
- 定义元组(元组:一个规定元素数量和每个元素类型的“数组”,而且每个元素的类型可以不相同)
let tup1: [string, number, boolean] = ['ab', 1, true]
-
对象(推荐使用接口来作为对象的类型注解)
// 创建对象 let obj: { name: string; age: number; sayHi: (name: string, age: number) => void; } = { name: 'zhangsan', age: 18, sayHi: function(name: string, age: number) { console.log(111) } } // or // 对象的类型注解 (分号可以省略):建立一种契约,约束对象结构 let obj: { name: string; age: number; sayHi: (name: string, age: number) => void; } // 创建对象 let obj = { name: 'zhangsan', age: 18, sayHi: function(name: string, age: number) { console.log(111) } }
-
接口(接口名称约定以 I 开头)
直接在对象后面写类型注解的坏处:1. 代码结构不简洁;2. 无法复用类型注解。
接口:为对象的类型注解命名,并为你的代码建立契约约束对象的结构
- 语法:
// 接口定义 interface IUser { name: string; age: number; sayHi?: (name: string, age: number) => void; // ?: 表示可选参数 [propname: string]: any; // 表示可以传递任何属性,值可以是任意类型 } // 创建对象 let obj: IUser = { name: 'zhangsan', age: 18, sex: '男' sayHi: function(name: string, age: number) { console.log(name) } } // 函数中使用接口 function fn(obj: IUser) { console.log(obj.name) } let o = { name: 'lisi', age: 20 } fn(o)
- 接口间的继承
interface IUser { name: string; age: number; } interface IGril extends IUser { sex: string; }
-
类型断言(手动指定 更加具体 的类型)
// 不指定,默认返回 Element 类型,可以用 as 指定具体类型 let img = document.querySelector('#img') as HTMLImageElement
-
枚举(JS 中没有枚举类型,Ts 中存在)
// 语法: enum 枚举名称 { Female, Male } enum Gender { Female, Male } // 注意:约定枚举名称以大写字母开头,多个成员用,隔开 // 枚举成员是只读的 let sex: Gender = Gender.Female // 0 sex = Gender.Male // 1
- 枚举成员的值
// 枚举成员的值默认是从 0 开始自增的数字(数字枚举) // 初始化枚举成员的值 enum Gender { Female = 1, Male } let sex: Gender = Gender.Female // 1 sex = Gender.Male // 2 // 字符串枚举(没有自增) enum Gender1 { Female = '女', Male = '男' } let sex1: Gender1 = Gender1.Female // 女 sex1 = Gender1.Male // 男
-
泛型
- 函数中的泛型 ( 一般用 T 表示 )
// 举例一 function join<T>(a: T, b: T) { return a + b } join<number>(1, 2) // 举例二 function join2<T, P>(a: T, b: P) { return a + b } join2<number, string>(1, '2') // 举例三 function myFun<T>(a: T[]) { return a + b } myFun<number>([1, 2])
- 类中的泛型
class SelectGirl { constructor(private girls: string[] | number[]) {} getGirl(index: number): string { return this.girls[index] } } const selectGirl = new SelectGirl(['小红', '小白', '小紫']) // 使用泛型一 class SelectGirl<T> { constructor(private girls: T[]) {} getGirl(index: number): string { return this.girls[index] } } const selectGirl = new SelectGirl<string>(['小红', '小白', '小紫']) // 使用泛型二 interface IGril { name: string; } class SelectGirl<T extends IGril> { constructor(private girls: T[]) {} getGirl(index: number): string { return this.girls[index].name } } const selectGirl = new SelectGirl<string>([ {name: '小红'}, {nameL '小白'}, {nameL '小紫'} ])
- 泛型的约束
// 泛型的约束 通过 extends 继承 class SelectGirl<T extends number | string> { constructor(private girls: T[]) {} getGirl(index: number): string { return this.girls[index] } } const selectGirl = new SelectGirl<string>(['小红', '小白', '小紫'])