重新巩固下typescript基础知识,顺便做做笔记
typescript安装
npm install -g typescript
ts基础类型
注意:均为小写
boolean、number、string、void、undefined、null、symbol
const a: string = 'a'
const a: number = 1
const a: boolean = false
// array两种
const a: number[] = [1, 2, 3]
const a: Array<number> = [1, 2, 3]
// symbol
const a: symbol = Symbol('key')
const b: symbol = Symbol('key')
a === b // false,symbol具有唯一性
// 当一个函数没有返回值,即void,只有undefined和null才可以赋给它
const a: void = undefined
// 类型断言两种方式
const len: number = (<string>value).length
const len: number = (value as string).length
ts其他类型
- any:任何类型,非必要不建议用,防止写成anyscript,失去typescript意义
- unknown: 3.0+引入,对照于any,unknown是类型安全的。 任何值都可以赋给unknown,但是当没有类型断言或基于控制流的类型细化时unknown不可以赋值给其它类型,除了它自己和any外。
let value: any;
value; // OK
let value2: unknown;
value2; // ERROR
- never:表示永不存在的值的类型,是任何类型的子类型,也可以赋值给任何类型
// 永远不会有返回值
function error(message: string): never {
throw new Error(message);
}
- 元祖:表示一个已知元素数量和类型的数组,各元素的类型不必相同。
接口
interface User {
name: string;
age: number;
desc?: string; // 可选属性
readonly gender: string; // 只读属性
friend: (person: string) => string // 函数类型
}
- 属性检查
对象字面量存在任何“目标类型”不包含的属性时,会报错
interface Size {
width: number;
}
function SizeFunc (size: Size) {
return size.width
}
// error: 'height' not expected in type 'Size'
const result = SizeFunc({width: 5, height: 6})
如上,有三种解决方式:
// 1、类型断言
const result = SizeFunc({width: 5, height: 6} as Size)
// 2、添加字符串索引签名(除了定义的width,其他属性均可传入)
interface Size {
width: number;
[propName: string]: any;
}
// 字面量赋给一个新的any变量,不建议这么做
const newResult: any = {width: 5, height: 6}
const result = SizeFunc(newResult)
- 可索引类型
当对象的key和value有共通性,则可以用可索引
// 学生A信息
studentA = {
name: 'A',
age: '12'
}
// 学生B信息
studentB = {
name: 'B',
age: '15',
gender: 'male'
}
// 则可以定义interface为
interface Student {
[key: string]: string;
}
- 继承接口
类似不同对象变量有共同的一部分属性,可以提出来写成一个继承接口
interface AddInfo {
id: string;
name: string;
status: number;
type: number;
}
interface DetailInfo {
id: string;
name: string;
status: number;
type: number;
created: number;
updated: number;
}
// 上述可写为
interface AddInfo {
id: string;
name: string;
status: number;
type: number;
}
interface DetailInfo extends AddInfo {
created: number;
updated: number;
}
// 也可继承多个
……
interface DetailInfo extends AddInfo, UpdateInfo {
……
类
- 抽象类
- 作为其他派生类基类使用,不会被实例化。
- abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法。
- 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
- 抽象类中的抽象方法只是声明,不包含具体的功能。
- 派生类必须定义抽象类中的抽象方法的具体实现(除非该派生类也是抽象类)。
- 派生类中定义的非抽象类的方法,实例后无法调用。
// 官网例子
abstract class Department {
constructor(public name: string) {
}
printName(): void {
console.log('Department name: ' + this.name);
}
abstract printMeeting(): void; // 必须在派生类中实现
}
class AccountingDepartment extends Department {
constructor() {
super('Accounting and Auditing'); // 在派生类的构造函数中必须调用 super()
}
printMeeting(): void {
console.log('The Accounting Department meets each Monday at 10am.');
}
generateReports(): void {
console.log('Generating accounting reports...');
}
}
let department: Department; // 允许创建一个对抽象类型的引用
department = new Department(); // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误: 方法在声明的抽象类中不存在
- 访问限定符
public: 可被外部访问
private: 只能类内部访问,外部不能访问
protected: 可被类内部或类的子类(派生类)访问
- class可作为接口,且实例化后,可作为变量初始值使用
函数
- 重载
为函数参数定义类型,提前为所传参数不存在的功能报错
// 不加ts接口定义
function Func(a: number, b?: number, c?: number) {
if (a) {
a = b = c
} else if (a && c) {
a = c
b = 2
}
return {
a: a,
b: b,
c: c
}
}
Func(1) // 不报错
Func(1, 2) // 不报错
加入ts接口定义后
泛型
不确定调用时传入的类型,依靠调用时传入的类型作为传出的参数类型及返回值类型
function Func<T>(arg: T): T {
return arg
}
const myFunc: <T>(arg: T) => T = Func
多个类型参数
function Func2<T, U>(arg2: [T, U]): [T, U] {
return [arg2[0], arg2[1]]
}
泛型变量,例如需要获取length属性一类
function FuncArr<T>(arr: Array<T>) {
return arr.length
}
泛型约束
可以使用继承来约束<T extends xx>
type Params = string | boolean
class Name<T extends Params> {
……
}
const newP = new Name<number>() // 报错
泛型约束与索引类型
// obj 是对象类型,key 无法在 obj 取到任何值
function getProps(obj: object, key: string) {
return obj[key] // error
}✘
// 仅对 obj 做了泛型约束,key 无法确定是否在 obj 上,也会报错
function getProps<T extends object>(obj: T, key: string) {
return obj[key] // error
}✘
// 对 key 也进行约束,把它约束为只存在于 obj 属性的类型
function getProps<T extends object, U extends keyof T>(obj: T, key: U) {
return obj[key] // ok
}
多重类型进行泛型约束的写法
interface A
interface B
// 第一种
interface C extends A, B
class Func<T extends C> {}
// 第二种
class Func<T extends A & B> {}
泛型与 new
// 声明泛型T是构造函数需要借助new,否则会报错
function factory<T>(type: {new(): T}): T {
return new type() // ok
}
参考: