propTypesのおさらい
オライリーから出ている「Reactビギナーズガイド」を読んで、サンプルで載っているコードをtypescriptに書き直しながら勉強をしています。
propTypesはes5のjsでは次のように使います。
propTypes: {
defaultValue: React.PropTypes.string.isRequired;
}
何をやっているかというと、Propsとしてコンポーネントに渡されるデータの型や必須の有無をコンポーネント側で定義しておき、変な値が渡されないようにする制約のようなものです。
別に書かなくてもコードの動作自体は可能です。
propTypesってtypescriptで果たして必要なのか
typescriptではPropsの型はコンポーネント側で明示的に指定しないといけません。
interface ButtonProps{
value: string;
}
class Button extends React.Component<ButtonProps, {}> {
// ... //
}
のように。
これは非常に面倒なことでありますが、vs codeなどでシンタックスハイライトや入力補完ができるのも、この型を明示しなければならない制約の恩恵と言えます。
で、typescriptでpropTypesが果たして必要かというと、調べたところこれはどうも必要なさそうです。
当たり前ですが、すでにinterfaceなどで型を定義していますので、さらにpropTypesで型を定義しても二重に同じことを書いているだけになります。
ところで実はtypescriptでもpropTypesは書けます。
typescriptでpropTypesを記述する
まずnpmでインストール
npm install --save @types/prop-types
コードではこんな感じで書けます。
import * as React from 'react';
import * as PropTypes from 'prop-types';
interface Button {
headers: string[];
}
class Button extends React.Component<ButtonProps, {}> {
static propTypes = {
headers: PropTypes.arrayOf(PropTypes.string)
};
// ... //
}
この機能、なんのために必要なんだろうと気になって調べたところもっともらしい答えがgithubのtypescriptのリポジトリのissueにありました。
typescriptにおけるPropTypesの必要性
What about the case when building a react library to be used by others. Others may not be using typescript. It would be nice to have a way to generate PropTypes when creating the distributed lib so other developers will be able to get PropType validation during development when using the library. React then strips theses away when building production.
要約すると、
es5とかtypescript以外で書いている他人が、自分がtypescriptで作ったreactライブラリを使用する際に、変なPropsが渡されたらきちんとwarningを出して上げなくてはいけない。
typescriptでbuildする時には(自分が使う分には)Propsに想定外の型が送られてきたら制約に引っかかりbuildは失敗してエラーに気づけるけど、buildした後はその制約はもう消えてしまうので、きちんとコードとして制約を残すにはpropTypesを書いておかなくてはならない。
といった趣旨でした。
複数人で、typescript以外のjsとtypescriptが入り乱れる環境での開発を強いられる場合は必須の機能なんですね。
また一つ勉強になりました。