TypeScriptでReactを扱ってるときにReactDOM.render
で意味が分からない型エラーが起きることがあります。
TS2605: JSX element type 'GithubPicker' is not a constructor function for JSX elements.
Types of property 'render' are incompatible.
Type '() => ReactNode' is not assignable to type '{ (): ReactNode; (): false | Element | null; }'.
Type 'ReactNode' is not assignable to type 'false | Element | null'.
Type 'undefined' is not assignable to type 'false | Element | null'.
この問題は@types/react
と@type/react-dom
のバージョンが混在している場合に発生します。
バージョンが混在しているかは、npm ls
やyarn list
を使うことで分かります。
✈ yarn list @types/react
yarn list v1.3.2
├─ @types/react-color@2.11.2
│ └─ @types/react@15.0.29
├─ @types/react-dom@16.0.3
│ └─ @types/react@15.0.29
└─ @types/react@16.0.34
Reactの場合、ライブラリ側の依存に@types
が含まれていると混在しやすいためこの問題が起きやすいようです。(また型定義が15 -> 16あたりで変わっていたのも原因)
この問題はインストールする@types/react
と@type/react-dom
のバージョンが混在しなければ解決します。
(Flatなインストールをすれば良い)
yarnの場合は"resolutions"
でバージョンを固定することで、yarn install
時に自動的にバージョンを統一できます。
npmはどうやるんだろ?npmも同様の機能提案が出ていたり、"resolutions"を擬似再現するツールがあります。
- Add Singleton Packages RFC. by usergenic · Pull Request #23 · npm/rfcs
- rogeriochaves/npm-force-resolutions: Force npm to install a specific transitive dependency version
package.json
の"resolutions"
にバージョンを指定することで固定できます。
"resolutions": {
"@types/react": "16.0.34",
"@types/react-dom": "16.0.3"
},
この状態でnode_modules
を削除してyarn install
し直すと、インストールされた@types/react
が混在しなくなります。
yarn list @types/react
yarn list v1.3.2
└─ @types/react@16.0.34
✨ Done in 0.55s.
実際に固定した例:
@typesは便利ですがsemverではない変更が入ってくることもあるため、何らかの方法で使うバージョンは固定した方が安全だと思います。