# 基础类型
# 定义数组类型的两种方式
let arr: Array<number> = []; // 不推荐
let arr1: number[] = []; // 推荐
arr = [1, 2, 3, 4, 5];
arr1 = [1, 2, 3, 4, 5];
1
2
3
4
5
6
2
3
4
5
6
# 定义对象类型
let obj: object = {};
obj = { name: 'zhangsan' };
1
2
3
4
2
3
4
# 定义null 和 undefined类型
let n: null = null;
let u: undefined = undefined;
1
2
3
4
2
3
4
# 定义symbol类型
let s1: symbol = Symbol('title');
let s2: symbol = Symbol('title');
console.log(s1, s2); // Symbol(title) Symbol(title)
console.log(s1 === s2); // false
1
2
3
4
5
6
2
3
4
5
6
# 定义任何类型 any
let any: any = 10;
any = 'hello';
any = true;
any = null;
1
2
3
4
5
6
2
3
4
5
6
# 定义unknown类型
// unknown类型的变量只能赋值给unknown类型和any类型
// unknown类型的变量不能直接赋值给其他类型的变量
// unknown类型的变量不能直接调用其方法
// unknown类型的变量不能直接作为函数的参数
// unknown类型的变量不能直接作为函数的返回值
let foo: unknown
foo = 'hello';
foo = true;
foo = null;
// let bar: string = foo; // error
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
# 定义void类型
// void类型的变量只能赋值为undefined和null
let v: void = undefined;
// v = null; // error
1
2
3
4
5
2
3
4
5
# 定义never类型
// never类型的变量只能赋值为undefined和null
// never类型的变量只能赋值为抛出异常的函数
// never类型的变量只能赋值为永远不会返回结果的函数
function error(message: string | number) {
switch (typeof message) {
case 'string':
console.log('string处理方式');
break;
case 'number':
console.log('number处理方式');
break;
default:
const check: never = message;
}
}
error('hello');
error(10);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 定义tuple 元组类型
// 元组类型的变量可以存储多个不同类型的值
let tuple: [string, number, boolean] = ['hello', 10, true]; // 推荐
let tuple1: Array<string | number | boolean> = ['hello', 10, true]; // 不推荐
const name = tuple[0];
1
2
3
4
5
6
2
3
4
5
6
# tuple的应用场景
// tuple元组的应用场景
// any 类型不严谨
// function useState(state: any) {
// let stateValue = state;
// const setState = (newState: any) => {
// stateValue = newState;
// }
// // 返回一个数组
// // (newState: any) => void 为函数类型
// const tuple: [any, (newState: any) => void] = [stateValue, setState];
// return tuple;
// }
// T 为泛型 代表任意类型 但是不确定 未来会是什么类型
// 但是可以确定的是 未来会是一个类型 不能是多个类型 否则会报错
function useState<T>(state:T) {
let stateValue = state;
const setState = (newState:T) => {
stateValue = newState;
}
// 返回一个数组
// (newState: any) => void 为函数类型
const tuple: [T, (newState:T) => void] = [stateValue, setState];
return tuple;
}
const [state, setState] = useState(0);
const [stateTitle, setStateTitle] = useState('hello');
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
# type 类型别名
// 1. 类型别名
type Name = string;
type NameResolver = () => void;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver){
if (typeof n === 'string') {
console.log('string');
} else {
n();
}
}
function n(){
console.log('function');
}
getName('string');
getName(n);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# this的默认推导
// this 是可以被推导出来的
// 但是如果是箭头函数,this就不可以被推导出来
// 但是可以通过call apply bind 来改变this的指向
// this 是可以被推导出来的 obj对象(typeScript推导出来的)
type thisType = {name:string}
function getName(this:thisType){
console.log(this.name + ' foo');
}
// const obj = {
// name: 'obj',
// getName() {
// console.log(this.name + ' getName');
// },
// }
const obj = {
name: 'obj',
getName:getName,
}
// 隐式绑定
obj.getName(); // obj getName
// 显示绑定
getName.call({name:'隐式绑定'}); // 隐式绑定 getName
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
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
# 类型断言 as
// <img id="lzp" />
// 案例1:获取dom元素,然后设置src属性,但是这里会报错,因为getElementById返回的是HTMLElement类型,
// const el = document.getElementById('lzp') // 默认是HTMLElement类型
const el = document.getElementById('lzp') as HTMLImageElement // as 断言为HTMLImageElement类型
el.src = 'https://www.baidu.com/img/bd_logo1.png'
// 案例2 Person是父类,Teacher是子类,
// getPersonName函数的参数是Person类型,但是Teacher类型也可以传入,但是Teacher类型没有studing方法,
// 所以会报错,这时候就可以使用类型断言,将Teacher类型断言为Person类型,就可以解决这个问题
class Person {
}
class Teacher extends Person {
studing() {
console.log('studing');
}
}
function getPersonName(p: Person) {
// p.studing() 类型“Person”上不存在属性“studing”
(p as Teacher).studing() // 断言为Teacher类型
}
const teacher = new Teacher()
getPersonName(teacher)
// 3.了解as any 和 unknown
const message = 'hello world'
// const num: number = message // 报错,类型“string”不能赋值给类型“number”
// const num: number = message as any as number // 两次断言,先断言为any类型,再断言为number类型
const num: number = (message as unknown) as number // 两次断言,先断言为unknown类型,再断言为number类型
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
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
# 字面量推算
type Metheod = 'GET' | 'POST' | 'PUT' | 'DELETE'
function request(url: string, method: Metheod) {
console.log(url, method)
}
const options = {
url: 'https://www.baidu.com',
method: 'GET'
}
// options.method 推出来的类型是 string 但是 request 函数的第二个参数是 Metheod 类型
// 类型“string”的参数不能赋给类型“Metheod”的参数。
// request(options.url, options.method)
// 通过类型断言as 可以解决这个问题
request(options.url, options.method as Metheod)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 非空类型断言
// message?: string 表示message参数是可选的 undefined | string
// !. 表示message一定不是undefined
function foo(message?: string) {
if(message) {
console.log(message.length);
}
console.log(message!.length);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 类型缩小
type msg = string | number | boolean;
function showMsg(msg: msg) {
if (typeof msg === 'string') {
console.log(msg);
} else if (typeof msg === 'number') {
console.log(msg);
} else {
console.log(msg);
}
}
// instanceof 用于判断对象是否是某个类的实例
function showMsg2(msg: string | Date) {
if (msg instanceof String) {
console.log(msg);
} else if (msg instanceof Number) {
console.log(msg);
} else {
console.log(msg);
}
}
class Animal {
foo(){}
}
class Dog {
bar(){}
}
function showMsg3(msg: Animal | Dog) {
if (msg instanceof Dog) {
console.log(msg);
} else if (msg instanceof Animal) {
console.log(msg);
} else {
console.log(msg);
}
}
// in 用于判断对象是否包含某个属性
type msg2 = {
too:() => void
}
type msg3 = {
boo:() => void
}
function showMsg4(msg: msg2 | msg3) {
if ('too' in msg) {
msg.too()
console.log(msg);
} else {
msg.boo()
console.log(msg);
}
}
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
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
# 可选链的使用 ?.
type person = {
name: string;
friend?: {
name: string;
age?: number;
sex?: string;
}
}
const p: person = {
name: 'zhangsan',
friend: {
name: 'lisi',
age: 20
}
}
// ?. 可选链 用于判断对象是否存在 不存在则返回undefined
console.log(p?.friend?.age); // 20
console.log(p?.friend?.sex); // undefined
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
# 参数的可选类型
// 可选类型是必须写在必选类型的后面
// 可选类型的参数可以不传
function add(a: number, b?: number) {
if (b) {
return a + b;
}
else {
return a;
}
}
add(1, 2);
add(1, undefined);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 对象类型和可选类型
// 对象类型
// 可选类型 ?
function foo(obj:{name:string,age:number,sex?:string}) {
console.log(obj.name);
console.log(obj.age);
}
foo({name:'zhangsan',age:20});
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# !!运算符和??运算符
// !! 运算符 用于将任意类型转换为布尔类型
const message = 'Hello World';
// Boolean 函数可以将任意类型转换为布尔值
// const flag = Boolean(message)
// !! 运算符可以将任意类型转换为布尔值
const flag = !!message;
console.log(flag);
// ?? 运算符 用于判断一个值是否为null或者undefined
let message: string|null = null;
// ?? 运算符可以将任意类型转换为布尔值
// const content = message ? message : 'Hello World';
const content = message ?? 'Hello World';
console.log(content);
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