3

I am trying to assign a value from an object of type TestInterface to another object of type TestInterface by accessing it with a dynamic key of type keyof TestInterface. However typescript seems to forget that this key is the same on both instances and therefore throws an error.

Since this sentence is hard to read, here is an example:

interface TestInterface {
    testKey?: NestesOptInterface;
    optKey?: string;
}

interface NestesOptInterface {
    key1?: string;
    key2?: string
}

const myObj : TestInterface= {

}

const myObj2 : TestInterface = {
    testKey: {
        key1: "test",
    }
}

const attributes : string[] = ['testKey', 'optKey']

const myTestKey: keyof TestInterface = attributes[0] as keyof TestInterface

/**Type 'string | NestesOptInterface | undefined' is not assignable to type '(NestesOptInterface & string) | undefined'.
 * Type 'NestesOptInterface' is not assignable to type 'NestesOptInterface & string'.
 * Type 'NestesOptInterface' is not assignable to type 'string'.(2322)**/
myObj[myTestKey] = myObj2[myTestKey]

//does work (obviously)
myObj['testKey'] = myObj2['testKey']

The tricky part is that testKey in the assignment of myTestKey should actually be any value of type string.

I was wondering whether this is a bug or how I can do this properly? Here is the Link to the Typescript Playground.

3
  • You can only pass a string to get a specific property. You cannot pass an object. That's why typescript shows that error, because keyof TestInterface could also be having the type NestesOptInterface and obviously you can't pass an object as property name. The weird thing is however that the error shows only to the assigned object (left one) even if you change that, the assigned one would only get the error. I would have expected to see an error on both of them. Commented May 6, 2022 at 10:52
  • Isn't keyof TestInterface only equivalent to "testKey" and "optKey" and therefore a string? I do not believe that this is the issue here. Commented May 6, 2022 at 11:11
  • True. You are right, it should be a string. It could be a bug. Consider opening a ticket in the TypeScript community. Because right now, Typescript gives the key the type of all possible values of the possible keys. And then it conflicts with the object method I mentioned. Commented May 6, 2022 at 14:00

2 Answers 2

4

I managed to find a not-too-dirty workaround that works for my use case. See example below:

//solution
myObj = {
    ...myObj,
    [myTestKey]: myObj2[myTestKey]
}

Note: myObj is now let instead of const

Typescript Playground

Sign up to request clarification or add additional context in comments.

Comments

0

You need to add type as -

const myTestKey: keyof TestInterface = 'testKey';

Playground

1 Comment

This does indeed solve the example, however - and I will edit my question accordingly - in my use case, testKey in the assignment actually represents just a value of type string, therefore I can not type the const explicitly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.