typescript - 从数组类型创建对象类型,其中键是数组中每个对象中的属性值
问题描述
给定一个对象数组的类型,我如何创建一个新的对象类型,其中键是数组对象中特定属性的值,对象的值是其中一个对象的类型仿制药。
使用 JS 代码,它看起来像这样:
const obj = arr.reduce((acc, element) => ({
...acc,
[element.name]: element.bar
}))
到目前为止,我有这个:
type ArrayToObject<Arr extends Array<CustomType<any>> = []> = {
[K in keyof Arr]: ExtractCustomTypeGeneric<Arr[K]>
}
type ExtractCustomTypeGeneric<A> = A extends CustomType<infer T> ? T : never;
type CustomType<T> = {
name: string,
foo: number,
bar: T
}
这给了我一个数组对象(因为K in keyof Arr
是索引号),而我希望属性键是name
. 不幸的是,类似[Arr[K]['name'] for K in keyof Arr]
的东西不起作用。
解决方案
您可以使用 获取数组中所有键的联合Arr[number]['name']
,然后您可以使用Extract
从数组中所有可能元素的联合中提取 ( Arr[number]
) 仅具有当前映射的项目name
:
type ArrayToObject<Arr extends Array<CustomType<any>> = []> = {
[K in Arr[number]['name']]: ExtractCustomTypeGeneric<Extract<Arr[number], { name: K }>>
}
type ExtractCustomTypeGeneric<A> = A extends CustomType<infer T> ? T : never;
type CustomType<T, K = string> = {
name: K,
bar: T
}
function createItems<T extends Array<CustomType<any, K>>, K extends string>(...a: T) : T{
return a;
}
let a = createItems({ name: "A", bar: ""}, { name: "B", bar: 0})
type R = ArrayToObject<typeof a>
//Same as
type R = {
A: string;
B: number;
}
推荐阅读
- java - 使用 servlet 和数据库限制登录尝试
- php - 当我输入错误密码时,此 PDO 登录表单也会记录我。如何解决?
- apache-spark - 将容量调度程序从默认更改为 ambari 上的 DominantResourceCalculator 后无法重新启动 spark2 thriftserver、spark-shell、sparksql
- mysql - SELECT 列表的表达式 #3 不在 GROUP BY 子句中,并且在尝试创建视图时包含非聚合列
- javascript - Paypal SDK 问题得到错误 [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
- python - 单个 FMU 的多核仿真
- java - Java DTO 和最终字段
- ffmpeg - 使用 FFMPEG 计算的 SSIM 值不是我所期望的
- requirejs - 如何使用 requireJS 加载车把
- xml - For each in XSLT 仅循环通过第一条记录