🦄

Next.jsでSVGR使用時にSVGの型がanyとなる問題の解決方法

2022/06/07に公開約1,400字

前提として投稿者の開発環境における各ライブラリのバージョンを記載しておきます。

ライブラリ バージョン
typescript 4.6.3
next 12.1.4
react 18.0.0
@svgr/webpack ^6.2.1

原因

Next.js11以降では既存の画像処理設定との競合を防ぐために画像ファイルに対する独自の型定義が導入されています。それが変更不可能で且つビルド毎に再生成されるnext-env.d.ts内に含まれているからだそうです。

next-env.d.ts
/// <reference types="next/image-types/global" />
node_modules/next/image-types/gobal.d.ts
declare module '*.svg' {
  /**
   * Use `any` to avoid conflicts with
   * `@svgr/webpack` plugin or
   * `babel-plugin-inline-react-svg` plugin.
   */
  const content: any

  export default content
}

解決方法

SVGRをプロジェクトで使用できるようにWebpackの設定をカスタマイズをします。

next.config.js
module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      use: ["@svgr/webpack"]
    });
    return config;
  },
}

Next.jsプロジェクト下に型定義ファイルを作成します。

# 命名は各自任意で
$ touch index.d.ts

作成した型定義ファイルにsvgのアンビエント宣言を記述します。

index.d.ts
declare module '*.svg' {
  const content: React.FC<React.SVGProps<SVGElement>>;
  export default content;
}

tsconfig.jsonのincludeに型定義ファイルを追加します。

tsconfig.json
{
-  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+  "include": ["next-env.d.ts", "index.d.ts", "**/*.ts", "**/*.tsx"],
}

私の開発環境では上記方法でSVG画像をimportした際に型が推論されるようになりました。

  1. ⌘(コマンド)+Shift+pでコマンドパレットを開く
  2. Developer: Reload Window を選択
  3. 再読み込みをして反映されているか確認

Discussion

ログインするとコメントできます