2

I have two types A and B. Both have k as a common but with different types. But A got an additional field j. When I union both and use them like this:

type A = {
    k?: string;
    j?: boolean
}
type B = {
    k?: number;
}
type C = B | A;

function D({ k, j }: C) {
    console.log(j)
}

I am getting the TypeScript error saying Property 'j' does not exist on type 'B'.

Can someone explain this behavior?

Antajo Paulson
  • 555
  • 1
  • 4
  • 15
  • Object types in TS are open, not sealed; extra properties are generally allowed, so a value of type `B` might have a `j` property of any type at all, as shown [in this example](https://tsplay.dev/w1xqlW). Does that fully address the question? Or am I missing something? – jcalz May 26 '23 at 15:28
  • 1
    Typescript does what it should do, you won't be able to just destruct as you currently trying to do – wonderflame May 26 '23 at 15:28
  • 1
    Since you dont provide any value for "j" typescript is infering C type is B – Bruno Miguel May 26 '23 at 15:31
  • @BrunoMiguel Maybe I should have phrased the question better. What if I am using the type `C` as a function argument and try to destruct the `j`. BTW I have updated the question. – Antajo Paulson May 26 '23 at 15:38
  • When you do: type C = B | A; you are really saying C can be of type either B | A. Now on your function declaration: function D({ k, j }: C), you are saying the the input type must be of type C. Since it can be of type C, it can be either A or B. Typescript cant be sure if the object you are passing in has the property J. you could pass in an object of type A in the case it would work, but you can also pass in an object of type B and in that case you would not have "j" property in it. So since both A or B can be pass in, typescript cant be sure that "j" will be present. – Bruno Miguel May 26 '23 at 16:04
  • Maybe you want an intersection type and not an union: type C = B & A; – Bruno Miguel May 26 '23 at 16:07

0 Answers0