问题描述
type复用时, 需要合并多个type, 合并时一个属性好几个type中有用到, 导致属性不唯一且类型也不相同, 使用&符号合并出来的属性类型为never,
//错误示例: 有冲突的合并
type type1 = {
num: number
}
type type2 = {
num: string
bool: string,
str: string
}
type type3 = {
num: boolean,
bool: boolean,
str: string
}
type GetMerge = type1&type2&type3 //合并结果是never; 内部bool与num合并冲突
//正常合并示例: 无冲突的合并
type type2 = {
num:string
}
type type3 = {
bool: boolean,
str: string
}
type GetMerge = type2&type3
//合并结果为
// {
// num:number,
// bool:boolean,
// str:string
// }
//目标结果, 无冲突正常合并, 有冲突则冲突属性变为联合类型,并且合并的类型个数动态, 即:合三个, 两个都可以 结果如下
type type1 = {
num: number
}
type type2 = {
num:string
}
type type3 = {
num: boolean,
bool: boolean,
str: string
}
//合并结果为
// {
// num:string|number|boolean,
// bool:boolean,
// str:string
// }
解决方案:
使用infer递归, 和数组实现不限个数, 冲突动态合并的效果, 代码实例如下
type type1 = {
num: number
}
type type2 = {
num:string
}
type type3 = {
num: boolean,
bool: boolean,
str: string
}
//下面为实现部分
//读取key值
type KeyofType<T> = keyof T
//读取值, P为keyof出来的key值
type GetType<T,P> = P extends KeyofType<T> ? T[P]:never
//结果类似 keyof type1 | keyof type2 | keyof type3
type MergeKeyType<T extends Array<any>> = T extends [infer X,...infer Rect]? KeyofType<X>|MergeKeyType<Rect>:never
//结果类似(P extends keyof type1 ? type1[P]:never)|(P extends keyof type2 ? type2[P]:never), 例:P等于num,则结果为number|string|boolean
type MergeValueType<T extends Array<any>,P> = T extends [infer X,...infer Rect]? GetType<X,P>|MergeValueType<Rect,P>:never
//合并整个值
type GetMerge<T extends Array<any>> = {
[P in MergeKeyType<T>]:MergeValueType<T,P>
}
type ff = GetMerge<[type1,type2,type3]> //调用合并, 数组内部合并对象可以动态个数例如[type1,type2]
// 合并结果为
// {
// num:string|number|boolean,
// bool:string|boolean,
// str:string
// }
const cc:ff = { //实例
bool: true,
str: "23232",
num: 123
}