typescript 自带了很多工具类型,通过看它的源码我们可以学习到 很多技巧 ,将它进行组合可以发挥无穷的潜力。以下是我总结的非常实用的技巧:
- 根据 model 的某些属性查询对象列表
type Student = { // 定义model
id: number; // 主键
name: string;
age: number;
}
interface IQuery<T> {
select(params: Partial<T>): T[];
}
class QueryStudent implements IQuery<Student> {
select(params: Partial<Student>): Student[] {
// @todo
}
}
合理的使用 T
(范型) 和 Partial
工具类型,可以帮助我们节约很多类型声明,Partial
将类型中的字段全变成可选类型,这样参数 params 的 key 就锁定在了 T
类型所拥有的 key
。
- 根据 model 更新数据
更新数据一般情况下是需要指定唯一id的,这个时候我们就需要用到类型推导了:
type PropsRequired<T, S extends keyof T> = {
[k in S]-?: T[k]
}; // 这个地方也可以是 Required<Pick<T, S>>
type ModelUpdateParams<T, S extends keyof T> = Partial<Pick<T, Exclude<keyof T, S>>> & PropsRequired<T, S>; // 用自带的工具组合: Partical<Omit<T, S>> & Required<Pick<T, S>>;
class StudentModel {
public update(params: ModelUpdateParams<Student, 'id'>) {
// @todo
}
}
ModelUpdateParams
类型的推导在于将非必须的字段取出来变成 Paritial 然后 和 必须的字段进行联合, 这样update的参数就必须包含有指定的字段名id了。
- 类 valueOf 推导
在 typescript 文档中有看到 keyof
但是却没有 valueOf
,其实有变通的方案:
type FunctionPropKeys<T> = {
[k in keyof T]: T[k] extends Function ? k : never;
}[keyof T]; // 这个写法就类似于 valueOf 了,取出了是函数类型的key
type FunctionProps<T> = Pick<T, FunctionPropKeys<T>>; // 我们声明了一个提取函数属性的类型