希望老师能够给讲解一下下面代码注释的 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回答

keviny79

2021-10-05

type MethodsType = {

  menu: {

    setActiveIndex: (indexstring=> string;

    setCollapse: (indexstring=> string;

  };

  tabs: {

    seteditableTabsValue: (editValuestring=> void;

    setTabs: (indexstring=> void;

    setTabsList: (indexstring=> void;

  };

}



// 1、模板字符串这里为什么要加 & string ,这个不太理解?

// 答:因为模板字符串中只允许出现string | number | bigint | boolean | null | undefined类型

type AddPrefix<OtherKeyPrefix> = `${Prefix & string}/${OtherKey & string}`

//type GetSpliceKey<Obj, Prefix> = AddPrefix<keyof Obj, Prefix>;


type GetSpliceKey<OtherKeyPrefix> = AddPrefix<OtherKeyPrefix>


// 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: (namenumber=> void;

    role: (namestring=> 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<TAB> = 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<TAB> : unknown

}


//  4———————获取所有函数的返回值类型

type GetMethodReturn<T> = {

  [K in GetSpliceKeys<T>]:

  K extends `${infer A}/${infer B}` ?

  GetFunc<TABextends (...argsany=> infer P ? P : never : never

}


type GetObjFunc = GetMethodReturn<MethodsType>


0
1
慕丝0266148
非常感谢!
2021-10-06
共1条回复

晋级TypeScript高手,成为抢手的前端开发人才

轻松驾驭 TypeScript 高级用法, 突破前端成长瓶颈

871 学习 · 425 问题

查看课程