在项目中我们常会提前声明一个的类型,用来规范变量。
类似于这样:
interface NormalOrInActiveStoreParams {
limit: number;
offset: number;
tags: string;
dc_id: number;
types: string;
keywords: string;
diff_day: number;
}
interface OutFlowAndSearchStoreParam {
dc_id: number;
limit: number;
offset: number;
}
-- 使用
getNormalOrInActiveStore(params: NormalOrInActiveStoreParams){
// 代码块
}
getOutFlowMapByIds(params: OutFlowAndSearchStoreParam){
// 代码块
}
这样的使用固然没有问题,但如果仔细观察会发现这两个接口其实只有好几个重复的字段,如果再多上几个函数和类型接口的话,代码就会出现大量重复的情况,并且修改起来也很麻烦,需要挨个修改,显然这样是不合理的。
遇到这种情况我们可以使用TypeScript内置的类型来解决:
type OutFlowAndSearchStoreParam = Pick<NormalOrInActiveStoreParams,"dc_id" | "limit" | "offset">;
这样一来,我们可以尽量少地写重复的类型,复用已有类型,让代码更加优雅容易维护。
下面是一些其他用例供参考:
Partial<T> & Required<T>(作用相反)
- 将类型 T 的所有属性标记为可选属性
type Partial<T> = {
[P in keyof T]?: T[P];
};
type Required<T> = {
[P in keyof T]-?: T[P];
};
-- 使用场景:
// 筛选项
interface StoreInfo {
order_date: string
record_date: string
delivery_date: string
createdAt_date: string
}
// 在列表的筛选项中我们要定义
getList(param: StoreInfo) {
// 代码块
}
// 如果在另外一个接口复用该类型且参数可选
getOtherList(param: Partial<StoreInfo>) {
// 代码块
}
Pick<T,K>
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
// 类似于_.pick(),过滤选择一些属性正
-- 使用场景见开头
Record<K, T>
-- 用于定义对象key,value类型
type Record<K extends keyof any, T> = {
[P in K]: T;
};
-- 使用
// 定义门店id(key)-门店信息(value) 的对象
const storeInfo: Record<number, Pick<StoreInfo, "order_date"| "record_date"> = {
1001: {
order_date: string
record_date: string
}
}
Omit<T,K>
-- 过滤移除指定的属性和Pick相反作用
const newStoreInfo: Omit<StoreInfo, "order_date"| "record_date"> // {createdAt: string}
Exclude<T, U> & Extract<T, U>
-- 取两者差集
type Exclude<T, U> = T extends U ? never : T;
-- 取两者交集
type Extract<T, U> = T extends U ? T : never;
-- 用例
const oldStoreInfo = Exclude<StoreInfo, "order_date" | "record_date" | "sign_time"> // sign_time
Extract 则正好相反取两者交集
const oldStoreInfo = Extract<StoreInfo, "order_date" | "record_" | "sign_time"> // order_date