简体   繁体   English

根据其他对象数组的值动态分配 object 属性

[英]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 开心的更好方法是什么?

Full code example at TS Playground TS Playground 上的完整代码示例

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 ?? '';

Typescript playground Typescript 操场

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.

相关问题 将数组元素分配为具有“计数器”值的对象属性 - Assigning array elements as object properties, with 'counter' value 将字符串数组的动态值分配给 typescript 中 object 的属性 - Assigning dynamically values of string array to properties of an object in typescript 是否有任何值可以重新定义对象字段或数组元素,而不是将引用分配给其他对象 - Is there any value to redefining objects fields or array elements instead of assigning reference to other object 基于其他属性动态限制 TypeScript 中 object 属性的类型 - Restricting types on object properties in TypeScript dynamically based on other properties 基于另一个 object 更新对象属性数组 - Updating an array of objects properties based on another object 根据属性从对象数组创建对象 - Creating object from array of objects based on properties 根据其他属性的值动态设置属性 - Setting properties dynamically in react based on value of other properties useStyles 不是根据变量变化动态分配属性 - useStyles is not dynamically assigning properties based on variable change 如何在对象数组中动态添加 object 值 - How to add object value dynamically in array of objects 根据属性值从数组中删除对象 - Removing an object from array based on properties value
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM