希望老师能够给讲解一下下面代码注释的 1,2,3项的源码?
来源:8-12 【 TS 泛型类+泛型约束组合应用】通用分页类优化【通用类,移植即用】

慕丝0266148
2021-10-04
//感谢老师能在百忙之中给解决问题,由于项目时间紧,没能完整的看老师视频,等项目结束了,从头补老师的视频;
//数据格式
type obj = {
menu: {
setActiveIndex: (index: string) => void;
setCollapse: (index: string) => void;
};
tabs: {
seteditableTabsValue: (editValue: string) => void;
setTabs: (index: string) => void;
setTabsList: (index: string) => void;
};
}
// 1、模板字符串这里为什么要加 & string ,这个不太理解?
type AddPrefix<Prefix, Keys> = ${Prefix & string}/${Keys & string}
type GetSpliceKey<T, K> = AddPrefix<K, keyof T>;
// 2、 GetSpliceKeys 后面的 [keyof T] 不理解为什么要加?
type GetSpliceKeys = {
[K in keyof T]: GetSpliceKey<T[K], K>
}[keyof T]
// 3、此方法是约束并找到obj模块下的每一个函数的返回值类型, 这个不理解,老师有更好的方法不?
type GetFunc<T, A, B> = T[A & keyof T][B & keyof T[A & keyof T]];
type GetMethod = {
[K in GetSpliceKeys]: K extends ${infer A}/${infer B}
? GetFunc<T, A, B> : unknown
}
type GetObjFunc = GetMethod;
1回答
-
type MethodsType = {
menu: {
setActiveIndex: (index: string) => string;
setCollapse: (index: string) => string;
};
tabs: {
seteditableTabsValue: (editValue: string) => void;
setTabs: (index: string) => void;
setTabsList: (index: string) => void;
};
}
// 1、模板字符串这里为什么要加 & string ,这个不太理解?
// 答:因为模板字符串中只允许出现string | number | bigint | boolean | null | undefined类型
type AddPrefix<OtherKey, Prefix> = `${Prefix & string}/${OtherKey & string}`
//type GetSpliceKey<Obj, Prefix> = AddPrefix<keyof Obj, Prefix>;
type GetSpliceKey<OtherKey, Prefix> = AddPrefix<OtherKey, Prefix>
// 2. 关于[keyof]
// 2.1
// [keyof T] 导致结果获取的是——冒号:后面 GetSpliceKey<keyof T[Key], Key>
// 执行的结果组成的联合类型,直接舍弃[Key in keyof T]
type GetSpliceKeys<T> = {
[Key in keyof T]: GetSpliceKey<keyof T[Key], Key>
}[keyof T]
// 2.2 来测试下第2个问题
type SubMenuType = {
subMenu: {
rights: (name: number) => void;
role: (name: string) => void;
}
}
// 输出 GetSpliceKey<keyof T[Key], Key> 执行的结果 "subMenu/rights" | "subMenu/role"
type Test = GetSpliceKeys<SubMenuType>
// 2.3 对2可以加泛型约束
type GetSpliceKeysIncrease<T extends object> =
{ [Key in keyof T]: GetSpliceKey<keyof T[Key], Key> }[keyof T]
// 2.4 自己可测试下这个
//type GetSpliceKeysResult = GetSpliceKeys<MethodsType>
// 3
// 3.1 T 为MethodsType类型 A为menu 获取的就是menu的值【依然还是一个对象】
type TestOne<T> = MethodsType["menu" & keyof MethodsType] //S100
// 3.2 keyof T[A & keyof T] 的意思是——获取 3.1 对象中的全部key组成的联合类型 "setActiveIndex" | "setCollapse".....
// 3.3 如果 B="setActiveIndex" 那么 B & keyof T[A & keyof T]=setActiveIndex
// 结合3.1 可以推出:T[A & keyof T] ["setActiveIndex"] 拿到的就是setActiveIndex对应的值
type GetFunc<T, A, B> = T[A & keyof T][B & keyof T[A & keyof T]]
// 3.4 [K in GetSpliceKeys<T>] 迭代出2.4 所有 path
// 例如:K="menu/setActiveIndex" 那么 A="menu" B="setActiveIndex"
// GetFunc<T, A, B> 进入3.3 获取到setActiveIndex对应的函数类型
// 迭代出所有函数类型
type GetMethod<T> = {
[K in GetSpliceKeys<T>]:
K extends `${infer A}/${infer B}` ? GetFunc<T, A, B> : unknown
}
// 4———————获取所有函数的返回值类型
type GetMethodReturn<T> = {
[K in GetSpliceKeys<T>]:
K extends `${infer A}/${infer B}` ?
GetFunc<T, A, B> extends (...args: any) => infer P ? P : never : never
}
type GetObjFunc = GetMethodReturn<MethodsType>
012021-10-06
相似问题