TypeScript入门
TypeScript 简称 TS 是拥有类型系统的 JavaScript 的超级 -JS 有的他都有 可以编译成 javaScript
- 添加了类型支持
- ts 是静态类型 编译时检查 区别 js 是动态类型 执行时检查
执行流程
code.ts → tsc code.ts →code.js →浏览器 & node
安装 & 简化运行 ts
- 安装: npm i -g typescript 或 yarn global add typescript 编译: tsc xxx.ts
- 版本查看 tsc-v
- npm i -g ts-node 使用:ts-node xxx.ts 注意:内部会隐式转换 只运行 不会编译成 js 代码
- tsc --init 可生成 ts 配置文件
数据类型
可以将 TS 中的常用基础类型细分为两类:1 JS 已有类型 2 TS 新增类型
- JS 已有类型
- 原始类型:
number/string/boolean/null/undefined
- 对象类型:
object
(包括,数组、对象、函数等对象)
- 原始类型:
- TS 新增类型
- 联合类型、自定义类型 (类型别名)、接口、元组、字面量类型、枚举、void、any 等
- 注意:
- _原始类型_在 TS 和 JS 中写法一致
- _对象类型_在 TS 中更加细化,每个具体的对象(比如,数组、对象、函数)都有自己的类型语法
- JS 已有类型
基本类型定义
// 基本数据类型定义
let courseName:string = '玩转Vue 3 全家桶'
let price:number = 129
price = 11
let isOnline:boolean = true
let courseSales:undefin
1
2
3
4
5
6
2
3
4
5
6
函数类型定义
# 1 函数类型基本使用
// 函数声明
function add(num1:number,num2:number):number{ return num1 + num2 }
// 箭头函数
const add = (num1:number, num2 :number) :number =>{ return num1 + num2 }
1
2
3
4
2
3
4
# 2 没有参数还回 void (空)
function greet(name:string):void{console.log(1)}
// 如果什么都不写,此时,add 函数的返回值类型为: void
const add = () => {}
// 这种写法是明确指定函数返回值类型为 void,与上面不指定返回值类型相同
const add = (): void => {}
// 但,如果指定 返回值类型为 undefined,此时,函数体中必须显示的 return undefined 才可以
const add = (): undefined => {
// 此处,返回的 undefined 是 JS 中的一个值
return undefined
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 3 函数类型可选参数 ?号 注意:可选只能出现在参数列表的最后 与 默认值 互斥
function mySlice(start?:number,end?:number):void{
console.log('起始索引:‘,start, '结束索引:', end)
}
1
2
3
2
3
# 4 函数重载
函数重载 使用场景:我们要求的参数是数字返回值也是数字,字符串其他类型同理
function reverse (x:number):number
let reverse = (x:string) => string
function reverse(x: number): number
function reverse(x: string): string
function reverse(x: number | string): number | string | void {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
对象类型定义
# JS 中的对象是由属性和方法构成的,而 TS 对象的类型就是在描述对象的结构(有什么类型的属性和方法)
对象类型的写法:
// 空对象
let person:{}={}
// 有属性的对象
let person:{name:string}={ name:'同学‘ }
// 既有属性又有方法的对象
// 在一行代码中指定对象的多个属性类型时,使用’;‘(分号)来分隔
let person:{name:string; sayHi():void} = { name:'jack',sayHi(){} }
// 对象中如果有多个类型,可以换行写:
// 通过换行来分隔多个属性类型,可以去掉 `;`
let person:{
name:string
sayHi():void
} = {
name:'jack',
sayHi(){}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 解释:
- 使用 {} 来描述对象结构
- 属性采用 属性 :类型的形式
- 方法采用 方法名(): 返回值类型 的形式
- 对象类型 带有参数的方法类型
- 如果方法有参数,就在方法名后面的小括号中指定参数类型
type Person = {
greet(name:string):void
}
let person:Person = {
greet(name){
console.log(name)
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 对象类型 箭头函数形式的方法类型
方法的类型也可以使用箭头函数形式
type Person = {
greet:(name:string) =>void}
let person: Person = {
greet(name){
console.log(name)
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 对象类型 对象可选属性
- 对象的属性或方法,也可以是可选的,此时就用到可选属性了
- 比如,我们在使用 axios({ ... }) 时,如果发送 GET 请求,method 属性就可以省略
- 可选属性的语法与函数可选参数的语法一致,都使用 ? 来表示
type Config = {
url:string
method?:string
}
function myAxios (config:Congig){
console.log(config)
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 对象类型 适用类型别名
// 创建类型别名
type Person = {
name:string
sayHi():void
}
// 使用类型别名作为对象的类型:
let person:Person = {
name:'jack',
sayHi(){}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
元组 Tuple
解释:
- 元组类型可以确切地标记出有多少个元素,以及每个元素的类型
// 元组 使用场景:已知将要存入的数据的类型及顺序
let me:[string,number]=['哈哈',22]
me = ['小欢',22]
1
2
3
2
3
- 字面量类型
- 使用模式:字面量类型配合联合类型一起使用
- 使用场景:用来表示一组明确的可选值列表
- 比如,在贪吃蛇游戏中,游戏的方向的可选值只能是上、下、左、右中的任意一个
// 使用自定义类型:
type Direction = 'up' | 'down' | 'left' | 'right'
function changeDirection(direction: Direction) {
console.log(direction)
}
// 调用函数时,会有类型提示:
changeDirection('up')
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 解释:参数 direction 的值只能是 up/down/left/right 中的任意一个
- 优势:相比于 string 类型,使用字面量类型更加精确、严谨
- 枚举类型
- 枚举的功能类似于字面量类型 + 联合类型组合的功能,也可以表示一组明确的可选值
- 枚举:定义一组命名常量。它描述一个值,该值可以是这些命名常量中的一个
// 创建枚举
enum Direction { Up, Down, Left, Right }
// 使用枚举类型
function changeDirection(direction: Direction) {
console.log(direction)
}
// 调用函数时,需要应该传入:枚举 Direction 成员的任意一个
// 类似于 JS 中的对象,直接通过 点(.)语法 访问枚举的成员
changeDirection(Direction.Up)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
解释:
- 使用
enum
关键字定义枚举 - 约定枚举名称以大写字母开头
- 枚举中的多个值之间通过
,
(逗号)分隔 - 定义好枚举后,直接使用枚举名称作为类型注解
类型断言
解释:
- 使用
as
关键字实现类型断言 - 关键字 as 后面的类型是一个更加具体的类型(HTMLAnchorElement 是 HTMLElement 的子类型)
- 通过类型断言,aLink 的类型变得更加具体,这样就可以访问 a 标签特有的属性或方法了
详细可查阅:http://ts.xcatliu.com/basics/type-assertion.html (opens new window)
- 使用
类型别名
使用
type
关键字来创建自定义类型- 类型别名(比如,此处的 CustomArray)可以是任意合法的变量名称
- 推荐使用大写字母开头
- 创建类型别名后,直接使用该类型别名作为变量的类型注解即可
type courseScore = '好' | '非常好' |'一般好'
let score:courseScore = '好'
1
2
2
- 类型接口
// 类型接口 TS独有 关键字 Interface 使用场景:别名类似
interface 极客时间课程 {
课程名字:string,
价格:number[],
受众:string,
讲师头像?:string|boolean,
获取口令?:string
}
let vueCourse: 极客时间课程 = {
课程名字:'玩转Vue 3全家桶',
价格:[59,129],
受众: '前端小老弟',
讲师头像:false,
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 泛型
interface VueCourse5{
name:string
price:number
}
type CourseProps = keyof VueCourse5
let k:CourseProps = 'name'
let k1:CourseProps = 'price'
// keyof 可以拆解类型 extends 可以进行类型判断 三元 T extends U ? X : Y 类型三元
// T extends U ? X : Y 类型三元表达式
type ExtendsType<T> = T extends boolean ? "重学前端" : "玩转Vue 3"
type ExtendsType1 = ExtendsType<boolean>
type ExtendsType2 = ExtendsType<string>
// extends 相当于 TypeScript 世界中的条件语句,
// 然后 in 关键字可以理解为 TypeScript 世界中的遍历。下面的代码中我们通过 k in Courses 语法,相当于遍历了 Courses 所有的类型作为 CourseObj 的属性,值的类型是 number。
type Courses = '玩转Vue 3'|'重学前端'
type CourseObj = {
[k in Courses]:number // 遍历Courses类型作为key
}
// infer 关键字 作用:给变量设置类型变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- 类写法
1
- TS 关键字及作用
- keyof keyof 与 Object.keys 相似 不过 keyof 是用来获取对象类型的键的
interface Person {
age: number;
name: string;
}
type Player = {
age: number;
name: string;
};
type PersonKeys = keyof Person; // --> "age" | "name"
type PlayerKey = keyof Player; // --> "age" | "name"
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- typeof typeof 用来返回一个值的 type
- extends extends 用来继承 只有 interface 和 class 才可以继承 type 关键字声明的类型别名无法继承
- in in 关键字可以生成映射类型 类似循环
enum Letter {
A = 'a',
B = 'b',
C = 'c',
}
type LetterMap = {
[key in Letter]: string;
};
// 等价于
type _LetterMap = {
a: string;
b: string;
c: string;
};
type Keys = 'name' | 'sex';
type PersonMap = {
[key in Keys]: string;
};
// 等价于
type _PersonMap = {
name: string;
sex: string;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- is is 用作类型保护
- infer infer 可以帮助我们推断出函数的返回值
# TS 关键字
TS关键字
! 断言操作符 忽略null与undefined
?. 链判断运算符 可选
?? 空值合并运算符 当左侧操作数为 null 或 undefined 时,其返回右侧的操作数,否则返回左侧的操作数。
?: 可选属性
& 交叉类型 可将多个类型合并为一个类似继承又不完全是
| 分隔符 联合类型 联合类型使用 | 分隔每个类型。联合类型通常与 null 或 undefined 一起使用
is 自定义类型保护的类型谓词 type predicate
type 类型别名定义
interface 类型接口定义
typeof 可获取一个变量的声明类型
keyof 获取类型的所有key-键
in 类似循环 可遍历枚举类型
TS中的一些内置类型
Partial<T>将类型属性变成可选
Required<T>将类型属性变成必选
Pick<T>从某个类型中挑出一些属性来
Mutable<T>将类型的属性变成可修改
Readonly<T>类型的属性变成只读
ReturnType 用来得到一个函数的返回值类型
Record 可以获得根据 K 中所有可能值来设置 key 以及 value 的类型
类型断言:俩种语法 <>尖括号 | as语法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
常见的泛型变量代表的意思
T type 类型
K key 表示对象中键类型
V value 表示对象中值类型
E element 表示元素类型
P props 表示属性
U 多个类型
function identity <T, U>(value: T, message: U) : T {
console.log(message);
return value;
}
console.log(identity<Number, string>(68, "Semlinker"));
解析分割
Number()
parseInt()
parseFloat()
@xxx 装饰器
装饰器语法
@Plugin({
pluginName: 'Device',
plugin: 'cordova-plugin-device',
pluginRef: 'device',
repo: 'https://github.com/apache/cordova-plugin-device',
platforms: ['Android', 'Browser', 'iOS', 'macOS', 'Windows'],
})
@Injectable()
export class Device extends IonicNativePlugin {}
装饰器分类
TS装饰器分为类装饰器、属性装饰器、方法装饰器和参数装饰器四大类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
类型体操:https://github.com/type-challenges/type-challenges/blob/master/README.zh-CN.md (opens new window)
编辑 (opens new window)
上次更新: 5/26/2022, 9:20:36 AM