Parent React component with TypeScript discrimination union passes values to a child component with React discrimination union

55 views Asked by At

For instance, we have a parent component where the types are defined as a discrimination union. Depending on the "mode" value, the types of values change. There's also a child component that should accept the same universal type. Keep in mind that this example is abstract, but the application in real-world scenarios exists, such as if we want to create a similar component for a form using react-hook-form.

Parent:

import React from 'react'
import Child from '@ui/example/child'

interface DateRange {
  from: number
  to: number
}

interface FirstTypeProps {
  mode: 'first'
  someDate: Date[]
  someFunc: (days?: Date[]) => void
}

interface SecondTypeProps {
  mode: 'second'
  someDate: Date
  someFunc: (day?: Date) => void
}

interface ThirdTypeProps {
  mode: 'third'
  someDate: DateRange
  someFunc: (range?: DateRange) => void
}

type Props = FirstTypeProps | SecondTypeProps | ThirdTypeProps

const Parent: React.FC<Props> = ({ mode, someDate, someFunc }) => {
  return (
    <div>
      ...
      <Child mode={mode} someDate={someDate} someFunc={someFunc} />
    </div>
  )
}

export default Parent

Child:

import React from 'react'

interface DateRange {
  from: number
  to: number
}

export interface FirstTypeProps {
  mode: 'first'
  someDate: Date[]
  someFunc: (days?: Date[]) => void
}

export interface SecondTypeProps {
  mode: 'second'
  someDate: Date
  someFunc: (day?: Date) => void
}

export interface ThirdTypeProps {
  mode: 'third'
  someDate: DateRange
  someFunc: (range?: DateRange) => void
}

type Props = FirstTypeProps | SecondTypeProps | ThirdTypeProps

const Child: React.FC<Props> = () => {
  return <div></div>
}

export default Child

However, when attempting to pass the values 'mode', 'someDate', and 'someFunc', I encounter the following error:

enter image description here

You can avoid this error with such a notation:

return (
    <div>
      ...
      {mode === 'first' && <Child mode={mode} someDate={someDate} someFunc={someFunc} />}
      {mode === 'second' && <Child mode={mode} someDate={someDate} someFunc={someFunc} />}
      {mode === 'third' && <Child mode={mode} someDate={someDate} someFunc={someFunc} />}
    </div>
  )

But to be honest, it looks like "not very clean code". How can I properly type the components?

0

There are 0 answers