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 extends U ? number : never; type TExtendExample = TExtends // number // 联合类型, 表示如果T中的类型是U的子集, 那么返回never, 否则返回T, 这个过程可以理解为对T中的类型进行一次遍历, 每个类型都执行一次extends type NonNullable1 = T extends U ? never : T type NonExample = NonNullable1 // string
Pick 英文意思挑选, 也就是从某种类型中挑选出一个或多个属性
interface Todo {
title: string
desc: string
Done: boolean
}
type TodoPreview = Pick
// type TodoPreview = {
// Done: boolean;
// }
// 实现
type MyPick = {
[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, 'title'> = {
title: '你好'
}
todo.title = '啊啊啊'; // 无法为“title”赋值,因为它是只读属性
// 实现
type myReadonly = {
readonly [K in keyof T]: T[K]
}
// 分析: 通过keyof拿到所有的key属性值组成联合类型, 然后通过in遍历类型,在属性值前面加上readonly, 值value则是 T[K]
// 通过上面案例还可以实现可选类型
type myOptional = {
[K in keyof T]?: T[K]
}
Exclude 语法: Exclude, 返回 T 中不存在于 U 的部分
// 回顾extends // // 联合类型, 表示如果T中的类型是U的子集, 那么返回never, 否则返回T, 这个过程可以理解为对T中的类型进行一次遍历, 每个类型都执行一次extends // type NonNullable1 = T extends U ? never : T // type NonExample = NonNullable1 // string // 自己实现Exclude type myExclude = T extends U ? never : T // 测试 // 分析: 对T也就是'a'|'b'遍历, a extends 'a'|'b', 返回never, 'b', 'a'|'c',返回'b', 所以上面的返回'b' type excludeExample = myExclude // 'b'
Partial 将传入的属性变为可选项
interface Todo {
title: string
desc: string
Done: boolean
}
type Partial = {
[P in keyof T]?: T[P]
}
type KeyOfExample1 = Partial
let keyofEx1: KeyOfExample1 = {
title: '1'
}
-? 将可选项代表的 ?去掉, 将该类型变成必选项, 与之对应的还有一个+?,是将可选项变成必选项
interface Todo {
title: string
desc: string
Done: boolean
}
type Mutable = {
-readonly [P in keyof T]: T[P]
}
type mutableExample = Mutable>
// 将Todo变成可读之后再变成可写
Required 将传入的属性变成必选项
type Required = {
[P in keyof T]-?: T[P]
}
class KeyCls {
name?: string;
age?: number;
}
const requiredExample: Required = {
name: "John",
} // 报错
const requiredExample2: Required = {
name: "John",
age: 20,
} // 正常
Record 将K中所有的属性转化为T类型
type myRecord = {
[P in K]: T
}
enum Methods {
GET = "get",
POST = "post",
DELETE = "delete",
PUT = "put",
}
type IRouter = myRecord 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
// {
// age: number;
// }
// 只需要实现成这样就行了, 也就是获取到age
type myOmit = Pick
// 排除name, 按照上面的 Exclude // 'age'
type myOmit = Pick>
// 测试
type myOmitExample = myOmit;
// type myOmitExample = {
// age: number;
// }
NonNullable:作用是去掉 T 中的 null 和 undefined。T 为字面量/具体类型的联合类型
// 4.8版本之前
type NonNullable = T extends null | undefined ? never : T;
// 4.8版本之后
type NonNullable = T & {}
infer 可以推荐一个类型变量, 相当于生命一个类型变量, 这个变量的类型取决于传入的泛型T
type F = T extends () => infer R ? R : T;
type F1 = F // string
type TObj = T extends { name: infer V, age: infer U } ? V : T
type TObjExample2 = TObj; // number;
ReturnType 获取函数返回值的类型
type ReturnType = 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
type ReturnUser = {
// name: string;
// age: number;
// }
以上就是TypeScript条件类型的详细内容,更多关于TypeScript条件类型的资料请关注IT俱乐部其它相关文章!
