GatsbyJS をTypeScript化してみて気付いたのですが、
defaultProps
を設定した際に props の型はundefined
型も許可してしまう問題があります。これではせっかくpropsの型定義をしても意味が無いですね。
そこで GatsbyJS の src/components/header.js をTypeScript化して header.tsx にしてみたものを例として解決方法を提示しておきます。
※GatsbyJS の src/components/header.js には defaultProps が元から定義してあるのですが、defaultPropsは最終的に廃止される予定とのことなので設定するかどうかについては注意です。詳細はこちらをご参照ください。
悪いdefaultPropsの設定例
.
.
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 の型と違うので怒ってくれる例
undefined だと怒ってくれません
解決方法
方法としては、
Propsの型定義をする際に、Intersection Types(&)
とtypeof
を使用して、 defaultProps の型定義も一緒にしてしまう方法です。
まずは defaultProps は const で変数として宣言してあげて、それをPropsの型定義をする際に一緒に当て嵌めてしまいます。
そして定義した defaultProps を Header.defaultProps に代入してあげます。
詳細は以下になります。
.
.
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型以外の型の値に設定してみた場合はもちろん怒ってくれますし、
defaultProps の値を undefined に設定してみた場合も、怒ってくれるようになりました。