LoginSignup
0
2

More than 3 years have passed since last update.

React + TypeScript で defaultProps の型定義をする

Posted at

GatsbyJS をTypeScript化してみて気付いたのですが、
defaultPropsを設定した際に props の型はundefined型も許可してしまう問題があります。これではせっかくpropsの型定義をしても意味が無いですね。
そこで GatsbyJS の src/components/header.js をTypeScript化して header.tsx にしてみたものを例として解決方法を提示しておきます。
※GatsbyJS の src/components/header.js には defaultProps が元から定義してあるのですが、defaultPropsは最終的に廃止される予定とのことなので設定するかどうかについては注意です。詳細はこちらをご参照ください。

悪いdefaultPropsの設定例

(悪い例)src/components/header.tsx
.
.
type Props = {
  siteTitle: string
}

const Header: React.FC<Props> = ({ siteTitle }) => (
  <header
    style={{
      background: `rebeccapurple`,
      marginBottom: `1.45rem`,
    }}
  >
  .
  .
  </header>
)

Header.defaultProps = {
  siteTitle: ``, // ここがstring以外の型だったら、一応は下記画像のように怒ってくれます。しかし、undefined型だと怒ってくれません。
}

defaultProps の型が string と undefined 以外だと、 Props の型と違うので怒ってくれる例

スクリーンショット 2021-02-24 17.50.21.png

undefined だと怒ってくれません

スクリーンショット 2021-02-24 18.07.54.png

解決方法

方法としては、
Propsの型定義をする際に、Intersection Types(&)typeofを使用して、 defaultProps の型定義も一緒にしてしまう方法です。
まずは defaultProps は const で変数として宣言してあげて、それをPropsの型定義をする際に一緒に当て嵌めてしまいます。
そして定義した defaultProps を Header.defaultProps に代入してあげます。
詳細は以下になります。

(良い例)src/components/header.tsx
.
.
type Props = {
  siteTitle: string
} & typeof defaultProps

const defaultProps = {
  siteTitle: ``,
}

const Header: React.FC<Props> = ({ siteTitle }) => (
  <header
    style={{
      background: `rebeccapurple`,
      marginBottom: `1.45rem`,
    }}
  >
  .
  .
  </header>
)

Header.defaultProps = defaultProps

defaultProps の値をstring型以外の型の値に設定してみた場合はもちろん怒ってくれますし、
スクリーンショット 2021-02-24 18.26.45.png

defaultProps の値を undefined に設定してみた場合も、怒ってくれるようになりました。
スクリーンショット 2021-02-24 18.28.10.png

参考にさせていただいたURL

Typing defaultProps

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2