Home > OS >  Typescript: How to use a union in an interface correctly?
Typescript: How to use a union in an interface correctly?

Time:09-12

This should have been simple but, when defining an interface with options type:

  options:
     Array<{
        title?: string;
        options: Option[];
      }>
    | Option[];

I'm using map function to loop over the array, something like this:

  {options.map((option) => (
              <SelectPrimitive.Group key={option.title}>

Then I won't be able to access option.title, ts will say this title property doesn't exist. But the moment I remove the second part of the union:

options:
     Array<{
        title?: string;
        options: Option[];
      }>

It will work. Why doesn't ts understand that it's a union type, and instead it selects the second part of the union?

CodePudding user response:

It actually understands that's a union type.

When using a union type A | B it means that the object can be of type A or type B. TS will do type checking taking into account both A and B. Common properties will work, but if a property is only on one type you need to narrow the type.

That's where your error is coming from.

CodePudding user response:

To answer your question about "how to do is how to check the type of the prop in real time", you can simply check with a if statement if the object option in the map, is an instance of Option. You could also just check the type of the first element in options before your map.

Example 1

options.map((option) => (
    if (option instanceof Option) {
        <SelectPrimitive.Group key={option.title}>
    }

...

Example 2

if (options.length !== 0 && options[0] instanceof Option) {
    options.map((option) => (
          <SelectPrimitive.Group key={option.title}>
          ...
}
  • Related