skip to content
天真笔录

TS学习笔记

/ 5 min read

数组 vs 元组

  1. 数组
const list1: number[] = [1, 2, 3]; // 方式一(推荐)
const list2: Array<number> = [1, 2, 3]; // 方式二
const list3: (number | string)[] = [1, 3, "2"]; // 使用联合类型声明多种类型
type User = { name: string; age: number }; // 使用类型别名
const list4: User[] = [
	{
		name: "litianzhen",
		age: 20,
	},
];
  1. 元组
const userInfo: [string, string, number] = ["monkey", "tiger", 100];

接口

interface Person {
  readonly firstName: string // readonly 只读属性
  lastName: string
  age?: number // 可选属性
  say(): string // 方法
  [prop: string]: // 索引签名 -> 绕开多余属性
}

function getFullName({firstName, lastName}: Arg) {
  return `${firstName} ${lastName}`
}

implements

interface Vegetables {
	color?: string;
	type: string;
}
class tomato implements Vegetables {
	color = "red";
	type = "vegetable"; // 必须声明type
}

extends

interface Tomato extends Vegetables {
	eat(): string;
}

定义函数类型

interface AddFunc {
	(num1: number, num2: number): number;
}
const add: AddFunc = (num1, num2) => num1 + num2;

Class

修饰符

class Person {
	public name: string;
	protected sex: string;
	private age = 20;
	sayHello() {
		console.log("hello");
	}
	constructor(name: string, sex: string) {
		this.name = name;
		this.sex = sex;
	}
}

class Student extends Person {
	constructor(name: string, sex: string) {
		super(name, sex);
	}

	getSex() {
		return this.sex; // 子类继承中可以使用
	}
}

const p = new Person("tianzhen", "man");
console.log(p.sayHello());
console.log(p.name);
console.log(p.sex); // 不可访问
console.log(p.age); // 不可访问

const s = new Student("hongli", "woman");
console.log(s.name);
console.log(s.getSex());
  1. 如果没有使用修饰符,默认为public
  2. private只能在自己类的内部使用
  3. protected可以在被继承的子类中使用

简化写法

class Teacher {
	name: string;
	constructor(name: string) {
		this.name = name;
	}
}
class Teacher {
	constructor(public name: string) {}
}

const t = new Teacher("litianzhen teacher");
console.log(t.name);

上面两种写法是等价的

getter/setter

class Student {
	constructor(private _name: string) {}

	get name() {
		return this._name;
	}

	set name(name) {
		this._name = "hello " + name;
	}
}

const stu = new Student("tianzhen");
console.log(stu.name);
stu.name = "hongli";
console.log(stu.name);

当不想暴露一些私有属性时,可使用private并提供get/set

单例

class Demo {
	private constructor(public name: string) {}
	private static instance: Demo;
	static getInstance(name: string) {
		if (!this.instance) {
			this.instance = new Demo(name);
		}
		return this.instance;
	}
}

const demo1 = Demo.getInstance("tianzhen");
const demo2 = Demo.getInstance("tianzhen1"); // 无效,只能实例一次
console.log(demo1.name); // tianzhen
console.log(demo2.name); // tianzhen
console.log(demo1 === demo2); // true

抽象类

  1. 把类的共性提取出来,然后在抽象类中定义
  2. 抽象类的抽象方法必须被实现
  3. 抽象类不能被实例化
abstract class Gemo {
	width = 0;
	height = 0;
	abstract getArea(): number;
}
new Gemo(); // 无法创建抽象类的实例

class Circle extends Gemo {
	getArea() {
		return 200;
	}
}
class Square extends Gemo {
	getArea() {
		return 200;
	}
}

TS补充类型

元组

可以看作是数组的扩展,表示已知元素数量和类型的数组

let tuple: [string, number, boolean];
tuple = ["a", 10, false];
tuple = ["a", 10]; // error
tuple = [10, "a", false]; // error

枚举

给一组数值赋予名字

enum Roles {
	SUPER_ADMIN, // 0
	ADMIN, // 1
	USER, // 2
}

默认从0开始:Roles.ADMIN === 1

enum Roles {
	SUPER_ADMIN = 1,
	ADMIN = "admin",
	USER = 2,
}

也可以赋予不同的值

Any

任意类型

let a: any;
a = 1;
a = false;
a = "ha";

void

没有类型

const log = (value: string): void => {
	console.log(value);
};

never

指那些不存在的值类型(异常,死循环)

const errorFun = (message: string): never => {
	throw new Error(message);
};

unknown

需配合类型断言来缩小范围

交叉联合类型

  • 交叉类型:& 取交集
  • 联合类型:| 取并集

泛型

定义函数、接口、类的时候,不预先指定具体的类型,而在使用时再制定类型

const getArray = <T, U>(param1: T, param2: U, times: number): [T, U][] => {
	return new Array(times).fill([param1, param2]);
};
getArray<number, string>("tianzhen", 1, 4);

tsconfig.json

  1. tsc 默认会对根目录所有ts进行编译 ;tsc file 不会使用配置文件
  2. include: []
  3. files
  4. exclude
  5. noImplicitAny: true 必须显示设置any
  6. strictNullChecks: true 强制校验null类型
  7. rootDir
  8. outDir
  9. checkJS
  10. allowJS