上一章:typeScript类型
extends
继承
继承父类接口的方法和属性
interface Person {
name: string;
age: number;
}
interface Student extends Person {
score: number;
}
// Student: name/age/score
项目中调用后台接口经常碰到新增和编辑,编辑的参数一般只比新增多个 id,这里就可以用 extends 来继承
interface AddApiParamsModel {
name: string;
window: number;
}
interface EditApiParamsModel extends AddApiParamsModel {
id: number;
}
同时继承多个:
interface AddApiParamsModel {
name: string;
window: number;
}
interface DeleteApiParamsModel {
id: number;
}
//同时继承新增和删除的类型,生成编辑接口的参数类型
interface EditApiParamsModel extends AddApiParamsModel, DeleteApiParamsModel {}
泛型约束
interface Person {
name: string;
age: number;
}
function getUsersByAge<T extends Person>(entities: T[], user: T): T[] {
return entities.filter((entity) => user.age === entity.age);
}
在调用 getUsersByAge 时传递的参数必须符合 Person 类型
interface SelectedDataModel<T extends string | number> {
checkAll: boolean;
selected: T[];
unselected: T[];
}
这里泛型限制类型必须为 string 和 number
条件判断
type GetString<T> = T extends string ? T : never;
type StringKey = GetString<"name" | "age" | 1>;
//相当于:
type StringKey = "name" | "age";
keyof 索引类型查询
用于获取某个类型上的所有属性名,得到联合类型
interface Person {
name: string;
age: number;
}
let personProps: keyof Person; // 'name' | 'age'
项目中会用到表格排序功能,可以用 keyof 通过表格数据类型获取排序字段名
//表格数据
interface TableData {
metricName: string;
startTime: number;
endTime: number;
}
interface FetchParamsData {
sort: { sortKey: keyof TableData; order: "asc" | "desc" };
}
//相当于
interface FetchParamsData {
sort: {
sortKey: "metricName" | "startTime" | "endTime";
order: "asc" | "desc";
};
}
T[K] 索引访问
用于获取 T 类型上 K 属性的类型
let personName: Person["name"]; // string
使用第三方包的某些属性类型:
import type { FormProps } from "ant-design-vue";
const handleFinish: FormProps["onFinish"] = (values) => {
console.log(values, formState);
};
in 映射类型
以相同的形式去转换旧类型里每个属性,产生新的类型
一般与 keyof 配合使用
interface Person {
name: string;
age: number;
}
type NewPerson = { [K in keyof Person]: string }; //{name: string; age: string}
- k 为类型变量,它会依次绑定到每个属性
- keyof Person 为需要迭代的属性名的集合(联合类型)
提取某些属性生成新的类型:
interface Person {
name: string;
age: number;
score: number;
}
type NewPerson = { [K in keyof "name" | "score"]: Person[k] }; //{name: string; score: number}
重新映射
使用 as对映射类型中的键进行重新映射,来实现属性的过滤或转换
比如,把属性名都变成大写,则可以使用重新映射来实现
interface Person {
name: string;
age: number;
}
type NewPerson = { [K in keyof Person as Uppercase<K>]: Person[K] };
//相当于
type NewPerson = { NAME: string; AGE: number };
as后面的就是把索引转换成的目标结果
这里 Uppercase 是 TS 内置的方法,用于大写转换 于是 Person 的所有属性就通过重新映射都转换成了大写
项目中,给属性的获取定义对应的 getter 函数,比如:name => getName(),也可以使用重新映射实现
interface Person {
name: string;
age: number;
score: number;
}
type NewPerson = {
[K in keyof Person as `get${Capitalize<K>}`]: () => Person[K];
};
//相当于
type NewPerson = {
getName: () => string;
getAge: () => number;
getScore: () => number;
};
原来的基础加上了 get,并且后面通过 TS 内置的类型 Capitalize 将内容首字母大写。
泛型工具
Partial
将类型的属性变成可选,注意这是浅 Partial
type Partial<T> = { [P in keyof T]?: T[P] };
可以通过递归实现简易的深度 Partial
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? deepPartial<T[P]> : T[P];
};
Required
将类型的属性变成必填
type Required<T> = { [P in keyof T]-?: T[P] };
Pick
从 T 中取出一系列 K 的属性
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
interface Person {
name: string;
age: number;
}
type PersonName = Pick<Person, "name">; //{ name: string; }
Exclude
从 T 中找出 U 中没有的元素
type Exclude<T, U> = T extends U ? never : T;
interface Person {
name: string;
age: number;
gender: string;
}
type PersonName = Exclude<"name" | "score", keyof Person>; //type PersonName = 'score'
Omit
从 T 中剔除某些属性
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
interface Person {
name: string;
age: number;
gender: string;
}
type Pers onAge = Omit<Person, "name" | "gender">; //{ age: number; }
修改接口中的某个属性:
interface Person {
name: string;
age: number;
}
type NewPerson = Omit<Person, "name"> & {
score: number;
};
//相当于
interface NewPerson {
age: number;
score: number;
}
Extract
从 T 中找出 U 中所有的元素
type Extract<T, U> = T extends U ? T : never;
剔除属性类型不为 string 的属性:
interface Person {
name: string;
age: number;
1: string;
}
type StringParams = Pick<Person, Extract<keyof Person, string>>;
//相当于:
type StringParams = {
name: string;
age: number;
};
其中:
type PersonName = Extract<keyof Person, string>;
//相当于
type PersonName = "name" | "age";
提取属性值为 string 的属性:
interface Person {
name: string;
age: number;
score: string;
}
type PersonValueType = {
[key in keyof Person]: Person[key] extends string ? key : never;
};
// 相当于:
// interface PersonValueType = {
// name: 'name';
// age: never;
// score: 'score';
// }
type PersonStringValueKey = PersonValueType[keyof Person];
// 相当于:
// "name" | "score" | never,其中never会被剔除
// type PersonStringValueKey = "name" | "score"
type StringValuePerson = Pick<Person, PersonStringValueKey>;
// 相当于:
// type StringValuePerson = {
// name: string;
// score: string;
// }