[SOLVED] Typescript warning when spreading optional keys

Issue

Im trying to understand why I get a compiler warning from Typescript when trying to create a new object based on an existing object of the same type.

In the code below you can see that spreading the key2 value causes the error Type 'string | undefined' is not assignable to type 'string'.. Although key2 is optional, i’m spreading the value from object1 which we know has a key2 entry.

type Test = {
  key1: string;
  key2?: {
    key3: string;
  }
}

const object1:Test = {
  key1: "hello",
  key2: {
    key3: "hi"
  }
}

const object2:Test = {
  ...object1,
  key2: { // error here
    ...object1.key2
  }
}

Type error:

Type '{ key3?: string | undefined; }' is not assignable to type '{ key3: string; }'.
  Types of property 'key3' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.(2322)

I’m just interested in understanding the behaviour here and the best way to handle this sort of situation.

TS Playground link: https://www.typescriptlang.org/play?#code/C4TwDgpgBAKhDOwoF4oG8BQUoGsIgEYAuKRAJwEsA7AcwG4td8AmAfhM22zxAGYTy1eowC+GMRgDGAeyqIo0gEYArCJODE481JyaESAIgAWEADanpBgDSMezDo275+UYxQOjxGKbPlLV6vZaSDqMAHQR-moaNk4g9uiOUBFhUeoEYXaeIkA

Thanks

Solution

The type of key2 is:

key2?: {
  key3: string;
}

That means key2 is:

  • allowed to be absent
  • allowed to be undefined
  • allowed to be { key3: string } (an object with key3 property that is is a string.)

What’s not allowed is an object that has an optional key3 property.

But if we look at the type of your spread:

const a = { ...object1.key2 }
// { key3?: string | undefined; }

That’s not a valid assignment of the key2 property because if its an object it must also have a key3 property with a string value.


To satisfy this interface, you need to prevent creating an object if key2 is undefined.

One way to do that would be:

const object2:Test = {
  ...object1,
  key2: object1.key2 && {
    ...object1.key2
  }
}

Playground

Answered By – Alex Wayne

Answer Checked By – Marilyn (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *