typescript 高阶类型
索引类型
keyof 会提取interface中的key
class keycls { name: string age: number } type keyclsexample1 = keyof keycls // name | age function getparams(params: keyof keycls) {} getparams('name') // 正常 getparams('age') // 正常 getparams('sex') // 报错
in 可以遍历枚举类型
type keys = 'a' | 'b' type obj = { [p in keys]: any; } // type obj = { // a: any; // b: any; // }
extends
type textends<t, u> = t extends u ? number : never; type textendexample = textends<number, number | string> // number // 联合类型, 表示如果t中的类型是u的子集, 那么返回never, 否则返回t, 这个过程可以理解为对t中的类型进行一次遍历, 每个类型都执行一次extends type nonnullable1<t, u> = t extends u ? never : t type nonexample = nonnullable1<null | string, null | undefined> // string
pick 英文意思挑选, 也就是从某种类型中挑选出一个或多个属性
interface todo { title: string desc: string done: boolean } type todopreview = pick<todo, 'done'> // type todopreview = { // done: boolean; // } // 实现 type mypick<t, k extends keyof t = keyof t> = { [p in k]: t[p] } // k in extends keyof t = keyof t, 意思是取值必须是在t的key上面取, 如果不传递取值默认为keyof t,所有的key, 内部取值是如果传递了k, 则属性就在k中任意一个
readonly 只读
interface todo { title: string desc: string done: boolean } const todo: pick<readonly<todo>, 'title'> = { title: '你好' } todo.title = '啊啊啊'; // 无法为“title”赋值,因为它是只读属性 // 实现 type myreadonly<t> = { readonly [k in keyof t]: t[k] } // 分析: 通过keyof拿到所有的key属性值组成联合类型, 然后通过in遍历类型,在属性值前面加上readonly, 值value则是 t[k] // 通过上面案例还可以实现可选类型 type myoptional<t> = { [k in keyof t]?: t[k] }
exclude 语法: exclude<t, u>, 返回 t 中不存在于 u 的部分
// 回顾extends // // 联合类型, 表示如果t中的类型是u的子集, 那么返回never, 否则返回t, 这个过程可以理解为对t中的类型进行一次遍历, 每个类型都执行一次extends // type nonnullable1<t, u> = t extends u ? never : t // type nonexample = nonnullable1<null | string, null | undefined> // string // 自己实现exclude type myexclude<t, u> = t extends u ? never : t // 测试 // 分析: 对t也就是'a'|'b'遍历, a extends 'a'|'b', 返回never, 'b', 'a'|'c',返回'b', 所以上面的返回'b' type excludeexample = myexclude<'a' | 'b', 'a' | 'c'> // 'b'
partial 将传入的属性变为可选项
interface todo { title: string desc: string done: boolean } type partial<t> = { [p in keyof t]?: t[p] } type keyofexample1 = partial<todo> let keyofex1: keyofexample1 = { title: '1' }
-? 将可选项代表的 ?去掉, 将该类型变成必选项, 与之对应的还有一个+?,是将可选项变成必选项
interface todo { title: string desc: string done: boolean } type mutable<t> = { -readonly [p in keyof t]: t[p] } type mutableexample = mutable<readonly<todo>> // 将todo变成可读之后再变成可写
required 将传入的属性变成必选项
type required<t> = { [p in keyof t]-?: t[p] } class keycls { name?: string; age?: number; } const requiredexample: required<keycls> = { name: "john", } // 报错 const requiredexample2: required<keycls> = { name: "john", age: 20, } // 正常
record<k, t> 将k中所有的属性转化为t类型
type myrecord<k extends keyof any, t> = { [p in k]: t } enum methods { get = "get", post = "post", delete = "delete", put = "put", } type irouter = myrecord<methods, (req: any, res: any) => void> // type irouter = { // get: (req: any, res: any) => void; // post: (req: any, res: any) => void; // delete: (req: any, res: any) => void; // put: (req: any, res: any) => void; // }
omit 排除某些字段
// 已经学习了pick和exclude, 则可以利用这两个实现omit class keycls { name: string; age: number; } // 假设 t 为 keycls, k为name, 结果是 // type myomit<keycls, 'name'> // { // age: number; // } // 只需要实现成这样就行了, 也就是获取到age type myomit<t, k extends keyof t> = pick<t, 'age'> // 排除name, 按照上面的 exclude<'name' | 'age', 'name'> // 'age' type myomit<t, k extends keyof t> = pick<t, exclude<keyof t, k>> // 测试 type myomitexample = myomit<keycls, "name">; // type myomitexample = { // age: number; // }
nonnullable<t>:作用是去掉 t 中的 null 和 undefined。t 为字面量/具体类型的联合类型
// 4.8版本之前 type nonnullable<t> = t extends null | undefined ? never : t; // 4.8版本之后 type nonnullable<t> = t & {}
infer 可以推荐一个类型变量, 相当于生命一个类型变量, 这个变量的类型取决于传入的泛型t
type f<t> = t extends () => infer r ? r : t; type f1 = f<string> // string type tobj<t> = t extends { name: infer v, age: infer u } ? v : t type tobjexample2 = tobj<{ name: number; age: string; }>; // number;
returntype<t> 获取函数返回值的类型
type returntype<t> = t extends (...args: any[]) => infer r ? r : any; functin getuser() { return { name: 'xxx', age: 20 } } type getusertype = typeof getuser; // type getusertype = () => { // name: string; // age: number; // } type returnuser = returntype<getusertype> type returnuser = { // name: string; // age: number; // }
以上就是typescript条件类型的详细内容,更多关于typescript条件类型的资料请关注代码网其它相关文章!
发表评论