TypeScript知识点记录

1、变量定义

在ts中:(冒号)后面都是在声明类型,要牢记

1.1 定义基本数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let isone: boolean = false;

let age: number = 18;

let str: string = 'str';
let str1: string = `hello ${str}`; // 也支持模版字符串的写法

let u: undefined = undefined;

let n: null = null;

// undefined和null是所有类型的子类型,可以赋值给任意类型,如下
let num: number = null;

// any是任意类型
let anyValue: any = 8;
anyValue = "小王";
anyValue = true;

// 联合数据类型,代表numOrString这个变量可以是数字也可以是字符串,其他类型均会报错
let numOrString: number | string = 1;
let numOrString: number | string = '1';

1.2 定义数组

1
2
3
4
5
// 定义子元素全是number的数组
let arr: number[] = [1, 2, 3, 4];
arr.push('123'); // push其他类型元素会报错
let arr1: any[] = [1, 2, 3, 4, '123', true]; // 定义任意类型的数组
let arr3: [number, string] = [1, '321']; // 定义指定子元素类型的数组,少写或者多写子元素都会报错

1.3 定义对象

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
interface Person {
name: string;
age: number;
}

// 和上面一样,多写或者少些属性都会报错
let man: Person = {
name: 'dd',
age: 18
}


// 如果希望属性的可选的,不一定存在的使用?即可,这样即使缺少age属性也不会报错
interface Person {
name: string;
age?: number;
}

let man: Person = {
name: 'dd'
}


// 给对象增加只读属性
// 和const不同的地方在于:readonly用在属性上面,而const用在变量上面
interface Person {
readonly id: number;
name: string;
age?: number;
}

let man: Person = {
id: 123,
name: 'dd',
age: 18,
}

man.id = 123; //重新赋值id会报错

1.4 定义函数

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
// 第三个number代表返回值的类型,这种写法参数只能是两个,少些或者多写会报错
function add(x: number, y: number): number {
return x + y;
}

let result = add(1, 2);


// 这种写法代表,z是可选参数,可选参数必须写在最后一项,不然会报错
function add(x: number, y: number, z?: number): number {
return x + y;
}


// 参数设置默认值的写法
function add(x: number, y: number = 10, z?: number): number {
return x + y;
}


// 函数的多种写法
const add1 = function (x: number, y: number = 10, z?: number): number {
return x + y;
}

// 将add1复制给新函数add2
const add2: (x: number, y: number, z?: number) => number = add1;

1.5 定义class

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
class Animal {
// public 公共的,在类里面、子类、类外面均可以访问,不写默认为public
// private 私有的,只有在类里面可以访问,只有Animal类可以访问
// protected 在类里面、子类均可以访问,类外面无法访问
// readonly 只读,不能修改
readonly name: string;
// 静态属性 无需实例化即可读取
static categoies: string[] = ['animal', 'bird'];
static isAnimal(a) {
return a instanceof Animal;
}
constructor(name: string) {
this.name = name;
}
run() {
return `${this.name} is running`
}
}
console.log(Animal.categoies);
const snake = new Animal('呆呆');
console.log(Animal.isAnimal(snake));


// 继承
class Dog extends Animal {
bark() {
return `${this.name} is braking`;
}
}

const xiaohei = new Dog('xiaohei');
console.log(xiaohei.bark())

// 重写父类方法
class Cat extends Animal {
constructor(name) {
// 重写父类方法必须用super调用
super(name);
console.log(this.name)
}
// 重写父类的run方法
run() {
return `咪咪${super.run()}`
}
}

const maomao = new Cat('maomao');
console.log(maomao.run())

1.6 定义泛型函数

泛型函数是参数和返回值类型相同的函数。

1
2
3
4
5
6
7
8
9
10
11
12
function echo<T>(arg: T): T {
return arg;
}

const res = echo('123');

// 两个参数时的写法
function echo<T, U>(arg: [T, U]): [U, T] {
return [arg[1], arg[0]];
}

const res = echo(['123', 233]);

1.5 定义枚举类型

枚举类型可以用于定义标识符,例如后端返回的字段 1代表成功 0 失败,可以不用写注释来记住。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
enum flag {
success=1,
error = -1
};
let s: flag = flag.error;
console.log(s) // -1


enum Color {
red,
blue,
green
}
let a: Color = Color.blue;
console.log(a) // 1,不赋值默认输出索引

enum Color {
red,
blue = 5,
green
}
let a: Color = Color.green;
console.log(a) // 6,red依然是0

1.6 定义any类型

1
2
let dom: any = document.querySelector('#test');
dom.style.color = 'red';

1.7 定义void类型

用于定义没有返回值的函数

1
2
3
4
function run(): void {
console.log('run')
}
run();

定义特殊类型变量

关于宿主环境里的类型,TypeScript 全部都给我们提供了,我们可以直接在代码中书写:Window 是 window 的类型,HTMLElement 是 dom 元素类型,NodeList 是节点列表类型,MouseEvent 是鼠标点击事件的类型……
查看更多类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
let w:Window = window
let ele:HTMLElement = document.createElement('div')
let allDiv: NodeList = document.querySelectorAll('div')

ele.addEventListener('click',function(e:MouseEvent){
const args:IArguments = arguments
w.alert(1)
console.log(args)
},false)


import { ref , Ref} from 'vue'
interface Todo{
title:string,
done:boolean
}
let todos:Ref = ref([{title:'学习Vue',done:false}])

extends 继承

user对象不加age属性会报错:Property ‘age’ is missing in type ‘{ name: string; }’ but required in type ‘User’

1
2
3
4
5
6
7
8
9
10
interface Name {
name: string
}
interface User extends Name {
age: number
}
const user: User = {
name: "sda",
age: 213,
}

interface 和 type 有什么区别

相同点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 都可以用来描述函数或者对象
interface User {
name: string
age: number
}

interface SetUser {
(name: string, age: number): void
}


type User = {
name: string
age: number
};

type SetUser = (name: string, age: number): void;

keyof语法

keyof 与 Object.keys 略有相似,只不过 keyof 取 interface或者type 的键。

实际应用:

假设有一个 object 如下所示,我们需要使用 typescript 实现一个 get 函数来获取它的属性值

1
2
3
4
5
6
7
8
const data = {
a: 3,
hello: "world",
}

function get(o: object, name: string) {
return o[name]
}

我们刚开始可能会这么写,不过它有很多缺点

  1. 无法确认返回类型:这将损失 ts 最大的类型校验功能
  2. 无法对 key 做约束:可能会犯拼写错误的问题

这时可以使用 keyof 来加强 get 函数的类型功能。

1
2
3
4
5
6
// 代码解读
// T extends object,入参T必须为object 类型
// K extends keyof T,限制K的类型必须是T的属性之一
function get<T extends object, K extends keyof T>(o: T, name: K): T[K] {
return o[name]
}

学习资料


TypeScript知识点记录
https://xypecho.github.io/2020/05/07/TypeScript知识点记录/
作者
很青的青蛙
发布于
2020年5月7日
许可协议