javascript - 如何在 TypeScript 中将数组转换为对象?
问题描述
我正在尝试输入下面的实用函数,它接受一个数组并返回一个对象,如下所示
const convertListToMap = (list, key, secondKey) => {
const map = {};
for (const ele of list) {
map[ele[key]] = ele[secondKey]
}
return map;
}
console.log(convertListToMap([{name: 'isaac', age: 17}, {name: 'john', age: 20}], 'name', 'age'));
console.log(convertListToMap([{race: 'chinese', language: 'mandarin'}, {race: 'malay', language: 'melayu'}], 'race', 'language'));
正如你所知道的key
,secondKey
它是动态的,取决于参数list
,所以我想generics
这是要走的路。下面是我的尝试
const convertListToMap = <
T extends object,
U extends keyof T,
V extends keyof T
>(
list: T[],
key: U,
secondKey: V
) => {
const map = {} as Record<U, V>;
for (const ele of list) {
map[ele[key]] = ele[secondKey];
}
return map;
};
但是,上面给了我错误Type 'T[U]' cannot be used to index type 'Record<U, V>'
,想知道我做错了哪一部分?
更新
我最近的尝试是更新map
如下的签名
const map = {} as Record<T[U], T[V]>;
for (const ele of list) {
map[ele[key]] = ele[secondKey];
}
return map;
通过最新的尝试,对map
变量的值赋值很好,但我在记录声明行遇到错误,错误如下
类型 'T[U]' 不满足约束 'string | 号码 | 象征'。类型 'T[keyof T]' 不可分配给类型 'string | 号码 | 象征'。键入'T[字符串] | T[号码] | T[symbol]' 不能分配给类型 'string | 号码 | 象征'。类型 'T[string]' 不能分配给类型 'string | 号码 | 象征'。类型 'T[string]' 不能分配给类型 'symbol'。类型 'T[keyof T]' 不能分配给类型 'symbol'。类型 'T[U]' 不能分配给类型 'symbol'。类型 'T[keyof T]' 不能分配给类型 'symbol'。键入'T[字符串] | T[号码] | T[symbol]' 不能分配给类型 'symbol'。类型 'T[string]' 不可分配给类型 'symbol'.ts(2344)
解决方案
最后一次尝试的问题是,它Record
似乎只期望string | number | symbol
,并且由于 TypeScript 不确定T[U]
会发生什么,因此它抛出了错误。我发现我们可以告诉 TS 更多信息T
如下
const convertListToMap = <
T extends { [key: string|number]: string | number },
U extends keyof T,
V extends keyof T
>(
list: T[],
key: U,
secondKey: V
) => {
const map = {} as Record<T[U], T[V]>;
for (const ele of list) {
map[ele[key]] = ele[secondKey];
}
return map;
};
从上面,我们告诉 typescript 这T
将是一个带有key
of的对象string
,并且值将是 type string | number
,这样,TypeScript 对定义感到满意Record<T[U], T[V]>
此解决方案效果很好,TS 可以正确推断
const personObj = convertListToMap([{name: 'isaac', age: 17}, {name: 'john', age: 20}], 'name', 'age')
// const personObj: Record<string, number>
const languageObj = convertListToMap([{race: 'chinese', language: 'mandarin'}, {race: 'malay', language: 'melayu'}], 'race', 'language')
// const languageObj: Record<string,string>
推荐阅读
- python - 如何在 Python 中编写 if 语句以更好地优化?
- django - 如何在自引用外键中引用所有具有现有查询的子对象?
- python - 我的“检查值字符串是否等于字典练习”的错误是什么?
- azure - 使用 F# 进行 Azure.Data.Tables 序列化
- javascript - 如何在 div 框中显示来自 javascript innerhtml 的文本输出,而不会导致文本溢出并具有 html/css 样式
- java - 当我尝试将代码推送到 Rev Driver Hub 时出现错误
- firebase - 如何在所有 Firebase 文档中添加新字段?
- javascript - 如何将图像放置在侧边栏的左下角?
- python - 将数据合并为单个电子邮件:Python
- google-bigquery - 在 BigQuery 中使用计划查询时,我可以在 EXTERNAL_QUERY 中使用 @run_time 吗?