Typescript 在项目中广泛使用,随着项目的复杂度上升,类型标注越来越繁琐。那么能否通过TS 类型来实现以下一些通用功能:
预先定义的Model 如下:
interface Person{
firstName: string;
lastName: string;
age: number;
address: Address[]
}
interface Address {
id: number;
province: string;
}
为了实现以上的功能,我们简单回顾一下会用到的知识点
返回一个对应类型的key 的联合类型
type Point = { x: number; y: number };
type P = keyof Point;
never
类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型。此外,变量也可能是 never
类型,当它们被永不为真的类型保护所约束时。当我们想要编译器不捕获当前值或者类型时,我们可以返回 never
类型
let obj = {
key1: string;
key2: never;
}
extends
除了用作接口继承之外,还可以用来做条件判定
interface Animal {
eat(): void
}
// 此处的extends 用作接口继承
interface Dog extends Animal {
bite(): void
}
// 此处用来做条件判定
type A = Dog extends Animal ? string : number //'string'
1.首先获取model 基本key
/**
*获取T 的key的对象,如果T[key]为基本类型,key与value 相等;反之为nerver
*使用keyof 获取新对象的key,如果key 对应的值为nerver会被过滤
**/
type GetBasicKeyType<T> = {
[key in keyof T]: T[key] extends string | number ? key : never;
}[keyof T];
//测试
type test2 = GetBasicKeyType<Person>;//type test = "firstName" | "lastName" | "age"
2.给基本类型增加Set方法
/**
* 获取基本类型的key
* 判定key为字符串时进行set+key 拼接
* 定义函数声明主体
**/
type GetBasicKeyAction<T> = {
[key in GetBasicKeyType<T> as key extends string? `set${Capitalize<key>}`: never] : (value: T[key])=>void
}
type test = GetBasicKeyAction<Person>;
// type test = {
// setFirstName: (value: string) => void;
// setLastName: (value: string) => void;
// setAge: (value: number) => void;
// }
3.2 给数组增加selecteById 方法
1.获取model 带有id 属性的数组key
type GetArrayKeyType<T> = {
[key in keyof T]: T[key] extends Array<{ id: number }> ? key : never;
}[keyof T];
type test = GetArrayKeyType<Person>;
//type test = 'address';
2.给数组增加获取方法
/**
* selecte + 获取带有id 的数组属性名称 + ById
* 定义函数主体
* 返回值使用了类型推断
*/
type GetArrayKeyAction<T> = {
[key in GetArrayKeyType<T> as key extends string ? `selecte${key}ById` : never]: (id: number) => T[key] extends (infer U)[] ? U : never;
}
//type GetElementType<T extends Array<any>> = T extends (infer U)[] ? U : never;
type test = GetArrayKeyAction<Person>
// type test = {
// selecteaddressById: (id: number) => Address;
// }
本文讨论一些基于TS类型实现的工具函数,TS 本身提供的类型比较有限,需要我们日常开发过程中自定义一些工具函数来减少一些类型重复定义工作(2021最后一天啦,祝大家新年大吉,心想事成^_^)。