LoginSignup
6
1

More than 1 year has passed since last update.

Next.js の _app.tsx で `'Component' cannot be used as a JSX component.` というエラーが出る

Posted at

環境

  • yarn v3.1.1
  • next v12.1.4
  • react v17.0.2
  • @types/react v17.0.33

背景

Next.js が自動生成する _app.tsx で下記のようなコードがある。

const App = ({ Component, pageProps }: AppProps) => (
  <Component {...pageProps} />
);

export default App;

ここがある時から下記のような型エラーを吐くようになった。

'Component' cannot be used as a JSX component.
  Its element type 'Component<any, any, any> | ReactElement<any, any> | null' is not a valid JSX element.
    Type 'Component<any, any, any>' is not assignable to type 'Element | ElementClass | null'.
      Type 'Component<any, any, any>' is not assignable to type 'ElementClass'.
        The types returned by 'render()' are incompatible between these types.
          Type 'React.ReactNode' is not assignable to type 'import("/Users/username/work/project-name/web/node_modules/@types/react-transition-group/node_modules/@types/react/ts5.0/index").ReactNode'.
            Type '{}' is not assignable to type 'ReactNode'.ts(2786)

どうやら ReactNode を返してほしいのに {} が返される可能性があり、それは許容できませんよと TypeScript が言っているらしい。

原因

エラー文の下から2行目を読むと、どうやら @types/react-transition-group/node_modules/ 配下の @types/react を参照しようとしている。

Type 'React.ReactNode' is not assignable to type 'import("/Users/username/work/project-name/web/node_modules/@types/react-transition-group/node_modules/@types/react/ts5.0/index").ReactNode'.

その中身を見てみると DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES という名前で確かに {} が ReactNode の一部に含まれている。

    /**
     * For internal usage only.
     * Different release channels declare additional types of ReactNode this particular release channel accepts.
     * App or library types should never augment this interface.
     */
    interface DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES {}
    type ReactNode =
        | ReactElement
        | string
        | number
        | ReactFragment
        | ReactPortal
        | boolean
        | null
        | undefined
        | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES[keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_REACT_NODES];

ref: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b57d67064938d173fa950cd519524445d20d2ef7/types/react/index.d.ts#L242-L257

最近 https://github.com/DefinitelyTyped/DefinitelyTyped/pull/65220 で追加された型のようで、このファイルの冒頭を見ると // Type definitions for React 18.2 と書いてある。
つまりプロジェクトの /node_modules/@types/react 内にある ReactNode の型が期待されているのに、なぜか /node_modules/react-transition-group/node_modules/@types/react 内にある ReactNode 型が参照されており、そのバージョンが異なっているためエラーになっているものと判断できる。

ちなみに yarn.lock の @types/react-transition-group の依存を見てみると、下記のように @types/react のバージョンは問わないという形になっているため、 yarn install 時に最新のバージョンが入ってしまったのかと思われる。

"@types/react-transition-group@npm:^4.4.0":
  version: 4.4.4
  resolution: "@types/react-transition-group@npm:4.4.4"
  dependencies:
    "@types/react": "*"
  checksum: 86e9ff9731798e12bc2afe0304678918769633b531dcf6397f86af81718fb7930ef8648e894eeb3718fc6eab6eb885cfb9b82a44d1d74e10951ee11ebc4643ae
  languageName: node
  linkType: hard

解決策

今回は package manager に yarn を利用しているので、その機能である resolutions を利用するため package.json に下記を追記する。

package.json
+  "resolutions": {
+    "@types/react": "17.0.33"
+  }

こうすることで依存ライブラリ経由で参照される react@types/react のバージョンを固定することができ、無事に冒頭の型エラーが消える。
ついでに next や react など、アプリケーション全体でバージョンが揃ってないとまずそうなライブラリを resolutions で固定しておくと良さそうだ。

参考

6
1
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
6
1