判別可能なユニオン型を用いたコンポーネントのProps制御


コンポーネントの実装で「特定のPropsの値を見て他のPropsを受け取るかどうか」を制御する実装がしたい場合に判別可能なユニオン型が便利です。

判別可能なユニオン型

type C = A | Bという型で、AとBが共通のプロパティを持っていてそのプロパティの値を見ることでCがAなのかBなのか判別できる型のことです。

詳しくはこちら

https://typescript-jp.gitbook.io/deep-dive/type-system/discriminated-unions

コンポーネントのProps制御

例えば、typeというPropsを用意してtype === 'リンク'ならリンクを表示して、type === 'button'ならボタンを表示するようなコンポーネントを実装するとします。この場合、リンクならhrefが必要ですが、onClick用の関数は不要です。逆に、ボタンならhrefは不要ですが、onClick用の関数が必要です。

実装

import { VFC } from 'react'

type LinkProps = {
  type: 'link'
  href: string
}

type ButtonProps = {
  type: 'button'
  onClick: () => void
}

type Props = LinkProps | ButtonProps

const LinkOrButton: VFC<Props> = (props) => {
  if (props.type === 'link') {
    return <a href={props.href}>リンク</a>
  } else {
    return <button onClick={props.onClick}>ボタン</button>
  }
}

export default LinkOrButton

コンポーネントを使う時

<LinkOrButton type="link" href="http://example.com/" />
<LinkOrButton type="button" onClick={() => {alert('hello')}} />

判別可能なユニオン型を使うことでコンポーネントに使わないPropsを渡さずに済みます。