typescript - 如何合并接口的所有值
问题描述
我正在尝试合并接口的所有值,例如:
interface IA {
a: string;
}
interface IB {
b: string;
}
interface IC {
c: string;
}
//...
interface IMap {
"a": IA;
"b": IB;
"c": IC;
//...
"z": IZ;
}
有没有办法创建一个类型,如:
type IAll = IMap["a"] & IMap["b"] & IMap["c"] & ... & IMap["z"];
我正在尝试使用这两个:
type valueMerge<T> = T[keyof T];
type valueMerge2<T extends keyof IMap = keyof IMap> = IMap[T];
// using
let t: valueof<IMap> = null as any;
let t2: valueof2 = null as any;
但是对于每一个,类型是IA | IB | IC | ... | IZ
而不是IA & IB & IC & ... & IZ
。
解决方案
这类似于关于如何以编程方式将 union 变成 intersection的问题,并且它有类似的解决方案。
通常,当您查找对象类型的所有属性时,您会得到所有属性的联合,如您所见。问题是这keyof T
是属性键的并集,查找键的并集会为您提供属性的并集,因为属性查找在属性键类型中是协变的......但您想要的是属性中的逆变操作键类型。(您可以在此处阅读有关协方差/逆变的更多信息,但基本上协方差意味着联合输入变为联合输出,而逆变意味着联合输入变为交叉输出)。
幸运的是,函数参数是逆变的,所以如果我们可以将你的接口映射到一个旧属性类型是函数参数的新接口,我们可以到达一个地方,这些函数类型的联合可以导致它们的参数相交。使用关键字在条件类型中进行类型推断infer
可以为我们做到这一点(参见“如果从逆变位置推断出任何候选者,则推断的类型是这些候选者的交集”的行)。
这是代码:
type IntersectProperties<T> = { [K in keyof T]: (x: T[K]) => void } extends {
[K in keyof T]: (k: infer I) => void
}
? I
: never;
的属性T
映射到函数参数,然后我们infer
一个单一的类型I
对应所有的函数参数,这将是一个交集。
让我们看看它是否有效:
type IAll = IntersectProperties<IMap>;
// type IAll = IA & IB & IC & ... & IZ
看起来挺好的。希望有帮助;祝你好运!
推荐阅读
- javascript - 为什么在函数中重新声明标识符会屏蔽同名参数?
- javascript - 如何修改嵌套对象的属性?
- terraform - 运行 terraform 输出时无法获取输出
- java - cloudrun 因 find_vma 失败而失败
- javascript - 我的取消静音命令 discord.js v11.5 有问题
- python - 我无法在 VSCode 中一次打开多个文件
- node.js - 通过 mongoose Expresss 在 mongodb 中执行 push 和 pull
- python - 在python中加载文件夹的最大csv文件
- python - 在 Windows 任务调度程序中使用服务帐户运行 python 脚本几秒钟后终止
- python - Python 抓取 - 具有多个文本元素的表格