[英]Dynamically assigning object properties based on the value of an array of other objects
Okay so I know the title can be a bit confusing, so let me explain.好的,我知道标题可能有点混乱,所以让我解释一下。
I have the following interfaces and an array of Items[]
:我有以下接口和
Items[]
数组:
interface Items {
step: number;
keyName: string;
value: string;
}
interface ReturnData {
foo: string;
bar: string;
baz: string;
}
const items: Items[] = [
{ step: 1, keyName: 'foo', value: 'fooVal' },
{ step: 2, keyName: 'bar', value: 'barVal' },
{ step: 3, keyName: 'baz', value: 'bazVal' },
];
Now imagine I want function that accepts Items[]
as a parameter, loops over the items
, and for each item assigns a new property with a key of keyName
and a value of value
to a new object of type ReturnData
, and then it finally returns that object as a promise.现在想象一下,我想要 function 接受
Items[]
作为参数,循环遍历items
,并为每个项目分配一个新属性,其键为keyName
,值为value
的新 object 类型为ReturnData
,然后它最终返回object 作为 promise。
For demonstration purposes I am using setInterval
here, but the same would work with a for loop
or other method.出于演示目的,我在这里使用
setInterval
,但同样适用于for loop
或其他方法。
const myFunc = (items: Items[]): Promise<ReturnData> => {
let index = 0;
let returnData: ReturnData = { foo: '', bar: '', baz: '' };
return new Promise(resolve => {
const interval = setInterval(() => {
/*
at index 0: items[index].keyName = 'foo' and items[index].value = 'fooVal'
at index 1: items[index].keyName = 'bar' and items[index].value = 'barVal'
at index 2: items[index].keyName = 'baz' and items[index].value = 'bazVal'
*/
returnData[items[index].keyName] = items[index]?.value;
if (items[index]?.step === items.length) {
clearInterval(interval);
resolve(returnData);
}
else {
index += 1;
}
}, 250);
})
}
(async () => {
const myResult = await myFunc(items);
console.log('myResult value is:', myResult);
/* myResult value is: { foo: 'fooVal', bar: 'barVal', baz: 'bazVal' } */
})();
In plain javascript this function would run properly and return myResult
as expected.在普通的 javascript 中,这个 function 将正常运行并按预期返回
myResult
。 But in Typescript I am getting the following error messages when I try to dynamically assign properties to returnData
at each iteration of my setInterval
.但是在 Typescript 中,当我尝试在
setInterval
的每次迭代中为returnData
动态分配属性时,我收到以下错误消息。
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'ReturnData'.
No index signature with a parameter of type 'string' was found on type 'ReturnData'.ts(7053)
and和
Object is possibly 'undefined'.ts(2532)
I have recently started learning Typescript, so my question is, how do I make Typescript understand what is happening here so that it doesn't throw the an error.我最近开始学习 Typescript,所以我的问题是,我如何让 Typescript 了解这里发生的事情,这样它就不会抛出错误。 I know a quick and dirty trick is to assign type
any
to my returnData
object to get rid of the errors, but that wouldn't be exactly "type-safe" if that is the correct terminology.我知道一个快速而肮脏的技巧是将类型
any
分配给我的returnData
object 以消除错误,但如果这是正确的术语,那将不完全是“类型安全的”。 What is a better way to go about and make typescript happy?关于 go 并让 typescript 开心的更好方法是什么?
Updating this line should solve your issue:更新此行应该可以解决您的问题:
Issue is that typescript can not associate they keyName of string type as being a key of ReturnData.问题是 typescript 无法将字符串类型的键名关联为 ReturnData 的键。
interface Items {
step: number;
keyName: keyof ReturnData; // only if you expect that ReturnData keyName will always belong to ReturnData
value: string;
}
typescript or typescript或
returnData[(items[index]!.keyName) as keyof ReturnData] = items[index]?.value ?? '';
Just change your interface like this, using keyof
operator.只需像这样更改您的界面,使用
keyof
运算符。
interface Items {
step: number;
keyName: keyof ReturnData;
value: string;
}
keyName is now: "foo" | keyName 现在是: "foo" | "bar" |
“酒吧” | "baz"
“巴兹”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.