简体   繁体   English

如何在打字稿中将一个对象的动态值添加到另一个不同类型的对象

[英]How to add dynamic values from one object to another object of different type in typescript

interface type1 {
    key1: string;
    key2: string;
    key3?: type3;
}

interface type2 {
    key1: string;
    key2: string;
    key5: string;
    key6: number;
}

interface type3 { 
    key5?: string;
    key6?: number;
}

const obj1: type1 = <type1>{};

const obj2: type2 = {
    key1: 'hi',
    key2: 'hello',
    key5: 'Hola',
    key6: 123
};

const obj3: type3 = <type3>{};

const array1: (keyof type2)[] = ['key1', 'key2'];
const array2: (keyof type3)[] = ['key5', 'key6'];


array1.forEach((key: keyof type2) => {
    obj1[key] = obj2[key]; /* Error occurred while adding value */
});

array2.forEach((key: keyof type3) => {
    obj3[key] = obj2[key]; /* Error occurred while adding value */
});

obj1.key3 = obj3;

console.log(obj1);

I have 3 objects of different types but some keys are common in objects.我有 3 个不同类型的对象,但某些键在对象中很常见。 I want to add values dynamically from one object to another.我想将值从一个对象动态添加到另一个对象。 I've added the code what I tried till now.我已经添加了我迄今为止尝试过的代码。

Is there any way to achieve it.有什么方法可以实现它。 Practically I've more keys than what I've put on the example.实际上,我有比我在示例中放置的更多的键。 assigning them one by one will be huge and inefficient.一一分配它们将是巨大且低效的。

Thanks in advance.提前致谢。

Here is a workable solution with minimal adjustments to your code ( Playground ):这是一个可行的解决方案,只需对您的代码( Playground )进行最少的调整:

const obj1: type1 = {} as type1;
const obj2: type2 = { key1: 'hi', key2: 'hello', key5: 'Hola', key6: 123 };
const array1 = ['key1', 'key2'] as const

array1.forEach(<K extends keyof (type1 | type2)>(key: K) => {
  obj1[key] = obj2[key]; 
});

// same with 2nd case (obj2, obj3, array2)

We can define array1 and array2 as tuples with const assertion, no need to annotate an explicit type.我们可以使用 const 断言将array1array2定义为元组,无需注释显式类型。

In order to get the computed property access with both obj1 and obj2 to work, the key has to be declared as generic type parameter K with constraint K extends keyof (type1 | type2) (means, restrict to all common properties of type1 and type2 ).为了使obj1obj2的计算属性访问都能工作,必须将key声明为泛型类型参数K并带有约束K extends keyof (type1 | type2) (意味着,限制为type1type2所有公共属性) . See this answer for an explanation of issues with computed property access with union key types and why generics are necessary.有关使用联合键类型的计算属性访问问题的解释以及为什么需要泛型,请参阅此答案

Object spread is a second alternative, where the types get a bit easier ( Playground ):对象传播是第二种选择,其中类型变得更容易( Playground ):

const obj1: type1 = {} as type1;
const obj2: type2 = { key1: 'hi', key2: 'hello', key5: 'Hola', key6: 123 };

const obj1New = {
  ...obj1,
  ...(['key1', 'key2'] as const).reduce((acc, cur) =>
    ({ ...acc, ...{ [cur]: obj2[cur] } }), {} as type1),
}

// same with 2nd case (obj2, obj3, array2)

You can try in operator to check if the key exists inside an object before assignment:您可以尝试in运算符在赋值之前检查键是否存在于对象中:

array1.forEach((key: keyof type2) => {
    if(key in obj1)
       obj1[key] = obj2[key]; /* Error occurred while adding value */
});

array2.forEach((key: keyof type3) => {
    if(key in obj3)
       obj3[key] = obj2[key]; /* Error occurred while adding value */
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM