当前位置: 代码网 > it编程>编程语言>Javascript > TypeScript条件类型示例全面讲解

TypeScript条件类型示例全面讲解

2024年05月15日 Javascript 我要评论
typescript 高阶类型索引类型keyof 会提取interface中的keyclass keycls {name: stringage: number}type keyclsexample1

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条件类型的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com