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ではない変更が入ってくることもあるため、何らかの方法で使うバージョンは固定した方が安全だと思います。