Home > Mobile >  React Typescript discriminated union gives compiling error but works on IDE
React Typescript discriminated union gives compiling error but works on IDE

Time:08-10

I have a component that has 2 properties. It may or may not accept one of those (say prop b), but you always need to pass the prop a. If the b prop is passed, it should change the typings of a.

interface FirstCase<T> {
  a: (param: CBParam<T>) => Element
  b: OtherInterface<T>
}

interface SecondCase {
  a: () => Element 
  b?: undefined
}

type ComponentProps<T> = FirstCase<T> | SecondCase

So, in my component im checking if the b prop is defined, and hoping that typescript infer the correct typings of a

function MyComponent<T>({a, b}: ComponentProps<T>): Element {
  return b ? a('some param') : a()
}

The thing is that in the IDE there is no error as I was expecting, but if I run npx tsc on the console, it complains that I need to pass a param to a (error TS2554: Expected 1 arguments, but got 0.)

CodePudding user response:

I believe you need a type guard function: https://www.typescriptlang.org/docs/handbook/advanced-types.html

Maybe specific example they use will help you: function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined; }

CodePudding user response:

I ended up doing type casting

return b ? a('some param') : (a as SecondCase['a'])()

CodePudding user response:

Destructuring a and b does not help the compiler here. If you instead keep it as props and then test b, it "knows" that a is related.

This does work without casting or compiler errors.

interface CBParam<T> {}
interface OtherInterface<T> {}

interface FirstCase<T> {
  a: (param: CBParam<T>) => Element
  b: OtherInterface<T>
}

interface SecondCase {
  a: () => Element
  b?: undefined
}

type ComponentProps<T> = FirstCase<T> | SecondCase

function MyComponent<T>(props: ComponentProps<T>): Element {
    return props.b ? props.a('some param') : props.a()
}

TypeScript Playground

  • Related