Home > other >  How to replace class properties with another class' properties dynamically in TypeScript
How to replace class properties with another class' properties dynamically in TypeScript

Time:03-13

I have the following TypeScript code that attempts to replace the values of the properties of one class instance with the values of another using a loop.

class A {

    n: number = 1
    s: string = "hello"

}

const myA1 = new A()
const myA2 = new A()
myA2.n = 2
myA2.s = "hi"

for (const k of Object.keys(myA1)) {
    /* Type 'string | number' is not assignable to type 'never'.
    Type 'string' is not assignable to type 'never'. */
    myA1[k as keyof A] = myA2[k as keyof A]
}

I know I could manually replace the properties like so:

myA1.n = myA2.n
myA1.s = myA2.s

However, I would like to replace them dynamically. Is there a way to tell TypeScript that I know the properties are of the same type? because they are (the same keys are being used for instances of the same class).

A follow-up question I also have is: what if the classes were different, but I also knew that their properties with the same name have the same type? Could the value replacement also be done in typescript?

I welcome any solutions or proposals following the same or another line of thought and logic. Avoiding things like type assertions would be fantastic.

Thank you

CodePudding user response:

You can do this via generics. Although, a cast is required for Object.entries(a) because TS isn't smart enough to know it is (keyof typeof a)[] which is just (keyof T)[]. Here's your solution:

class A {
    n: number = 1
    s: string = "hello"
}

const myA1 = new A()
const myA2 = new A()

function copyProps<T>(a: T, b: T) {
    for (const k of Object.keys(a) as (keyof T)[]) {
        a[k] = b[k];
    }
}

copyProps(myA1, myA2);

TypeScript Playground Link

CodePudding user response:

It is possible to use Object.assign() method:

The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

An example:

class A {

    n: number = 1
    s: string = "hello"

}

const myA1 = new A()
const myA2 = new A()


myA1.n = 1;
myA2.n = 2;
myA1.s = "s1"
myA2.s = "s2"

const assigned = Object.assign(myA1, myA2)
console.log(`assigned`, assigned)
console.log(`myA1`, myA1)
console.log(`myA2`, myA2)

Or you can use spread syntax:

class A {
    n: number = 1
    s: string = "hello"
}

const myA1 = new A()
const myA2 = new A()


myA1.n = 1;
myA2.n = 2;
myA1.s = "s1"
myA2.s = "s2"

const assigned = {...myA1, ...myA2};
console.log(`assigned`, assigned)
console.log(`myA1`, myA1)
console.log(`myA2`, myA2)

  • Related