# 基础类型

# 定义数组类型的两种方式

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

# 定义对象类型


let obj: object = {};
obj = { name: 'zhangsan' };

1
2
3
4

# 定义null 和 undefined类型


let n: null = null;
let u: undefined = undefined;

1
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

# 定义任何类型 any


let any: any = 10;
any = 'hello';
any = true;
any = null;

1
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

# 定义void类型


// void类型的变量只能赋值为undefined和null
let v: void = undefined;
// v = null; // error

1
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

# 定义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

# 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

# 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

# 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

# 类型断言 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

# 字面量推算


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

# 非空类型断言


// 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

# 类型缩小


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

# 可选链的使用 ?.


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

# 参数的可选类型


// 可选类型是必须写在必选类型的后面
// 可选类型的参数可以不传
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

# 对象类型和可选类型


// 对象类型
// 可选类型 ?
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

# !!运算符和??运算符


// !! 运算符 用于将任意类型转换为布尔类型
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
Last Updated: 2/23/2023, 9:05:22 AM