React Native + Typescriptで error TS2300: Duplicate identifier

Javascript

はじめに

React Native + Typescriptの環境構築で公式チュートリアル通りに進めていたら、「error TS2300: Duplicate identifier ‘AbortController’.」のようなエラーが出てきました。

本記事ではその原因と解決方法についてまとめます。

結論

先に結論を述べますと、複数のパッケージで型定義が重複している場合に出るエラーです。

パッケージのソースコードから、重複している片方の型定義を削除することで対応できます。
本記事では「patch-package」を使って型定義の修正を自動適用します。

環境

エラーについて

React Native + Typescriptの環境を作ろうとして、下記の公式サイトの説明に沿って設定を進めました。

Using TypeScript · React Native
TypeScript is a language which extends JavaScript by adding type definitions, much like Flow. While React Native is built in Flow, it supports both TypeScript a...

手順通り進めたのですが、yarn tsc を実行すると下記の様なエラーが出ました。

$ yarn  tsc
yarn run v1.22.11
$ /workspace/react_native_ts/node_modules/.bin/tsc
node_modules/@types/node/globals.d.ts:47:11 - error TS2300: Duplicate identifier 'AbortController'.

47 interface AbortController {
             ~~~~~~~~~~~~~~~

  node_modules/@types/react-native/globals.d.ts:411:15
    411 declare class AbortController {
                      ~~~~~~~~~~~~~~~
    'AbortController' was also declared here.

node_modules/@types/node/globals.d.ts:60:11 - error TS2300: Duplicate identifier 'AbortSignal'.

60 interface AbortSignal {
             ~~~~~~~~~~~

  node_modules/@types/react-native/globals.d.ts:388:15
    388 declare class AbortSignal implements EventTarget {
                      ~~~~~~~~~~~
    'AbortSignal' was also declared here.

node_modules/@types/node/globals.d.ts:67:13 - error TS2300: Duplicate identifier 'AbortController'.

67 declare var AbortController: {
               ~~~~~~~~~~~~~~~

  node_modules/@types/react-native/globals.d.ts:411:15
    411 declare class AbortController {
                      ~~~~~~~~~~~~~~~
    'AbortController' was also declared here.

node_modules/@types/node/globals.d.ts:72:13 - error TS2300: Duplicate identifier 'AbortSignal'.

72 declare var AbortSignal: {
               ~~~~~~~~~~~

  node_modules/@types/react-native/globals.d.ts:388:15
    388 declare class AbortSignal implements EventTarget {
                      ~~~~~~~~~~~
    'AbortSignal' was also declared here.

node_modules/@types/react-native/globals.d.ts:388:15 - error TS2300: Duplicate identifier 'AbortSignal'.

388 declare class AbortSignal implements EventTarget {
                  ~~~~~~~~~~~

  node_modules/@types/node/globals.d.ts:60:11
    60 interface AbortSignal {
                 ~~~~~~~~~~~
    'AbortSignal' was also declared here.
  node_modules/@types/node/globals.d.ts:72:13
    72 declare var AbortSignal: {
                   ~~~~~~~~~~~
    and here.

node_modules/@types/react-native/globals.d.ts:411:15 - error TS2300: Duplicate identifier 'AbortController'.

411 declare class AbortController {
                  ~~~~~~~~~~~~~~~

  node_modules/@types/node/globals.d.ts:47:11
    47 interface AbortController {
                 ~~~~~~~~~~~~~~~
    'AbortController' was also declared here.
  node_modules/@types/node/globals.d.ts:67:13
    67 declare var AbortController: {
                   ~~~~~~~~~~~~~~~
    and here.


Found 6 errors.

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

原因と解決方法

原因は「@types/node」と「@types/react-native」で型定義が重複しているためです。

解決方法としては「@types/node」のコードから該当部分をコメントアウトすることが挙げられます。

こちらのissueによると、patch-package で対応すればよいとのこと。

Transpiling errors with version 6.6.3 · Issue #203 · react-native-community/react-native-template-typescript
Expected results For there to be zero transpiling issues Observed results What happened? There are transpiling issues Logs Please add the log output here. dewi@...

早速やってみます。

patch-packageをインストール

下記コマンドでインストールします。

  • npmの場合
$ npm install --save-dev patch-package
  • yarnの場合
$ yarn add -D patch-package postinstall-postinstal

yarnの場合に「postinstall-postinstal」も必要な理由は、yarnの場合はpostinstallが実行されるのが「yarn add」と「yarn install」に限られ、「yarn remove」では実行されないからとのことです。

参考:React Nativeのライブラリをpatch-packageで手軽に修正する方法

package.jsonの編集

続いて、package.jsonの「scripts」項に下記項目を追加します。

...
"scripts": {
  "postinstall": "patch-package"
}
...

パッチ対象を修正

該当のソースコードを修正してエラーが出ないようにします。

Transpiling errors with version 6.6.3 · Issue #203 · react-native-community/react-native-template-typescript
Expected results For there to be zero transpiling issues Observed results What happened? There are transpiling issues Logs Please add the log output here. dewi@...

上記を参考にして、「node_modules/@types/node/globals.d.ts」の該当行をコメントアウトします。

node_modules/@types/node/globals.d.ts

     readonly aborted: boolean;
 }

-declare var AbortController: {
-    prototype: AbortController;
-    new(): AbortController;
-};
-
-declare var AbortSignal: {
-    prototype: AbortSignal;
-    new(): AbortSignal;
-    // TODO: Add abort() static
-};
+// declare var AbortController: {
+//     prototype: AbortController;
+//     new(): AbortController;
+// };
+//
+// declare var AbortSignal: {
+//     prototype: AbortSignal;
+//     new(): AbortSignal;
+//     // TODO: Add abort() static
+// };
 //#endregion borrowed

このときは、パッケージのソースコードを直接編集してください。
その後「yarn tsc」を行って、エラーがないことを確認しておきます。

修正patchの作成

パッチを作成するコマンドはこちらです。

  • npmの場合
$ npm run patch-package <パッケージ名>
  • yarnの場合
$ yarn patch-package <パッケージ名>

今回の対象パッケージは「@types/node」ですので、下記のように実行します。

$ yarn patch-package @types/node

実行してエラーが出なければ成功です。

成功すると「./patchs」ディレクトリにパッチファイルが作成されています。

パッチファイルの内容例はこちらです。

diff --git a/node_modules/@types/node/globals.d.ts b/node_modules/@types/node/globals.d.ts
index 5e359db..42c7c1e 100755
--- a/node_modules/@types/node/globals.d.ts
+++ b/node_modules/@types/node/globals.d.ts
@@ -64,16 +64,16 @@ interface AbortSignal {
     readonly aborted: boolean;
 }

-declare var AbortController: {
-    prototype: AbortController;
-    new(): AbortController;
-};
-
-declare var AbortSignal: {
-    prototype: AbortSignal;
-    new(): AbortSignal;
-    // TODO: Add abort() static
-};
+// declare var AbortController: {
+//     prototype: AbortController;
+//     new(): AbortController;
+// };
+//
+// declare var AbortSignal: {
+//     prototype: AbortSignal;
+//     new(): AbortSignal;
+//     // TODO: Add abort() static
+// };
 //#endregion borrowed

 //#region ArrayLike.at()

パッチが適用されるかを確認

node_modulesを削除して再度パッケージをインストール(yarn もしくは npm install)します。

Applying patches… と表示されるはずです。

...
[4/4] Building fresh packages...
success Saved lockfile.
$ patch-package
patch-package 6.4.7
Applying patches...
@types/node@16.7.10 ✔
Done in 93.65s.

node_modules/@types/node/globals.d.ts」を確認し、パッチが適用されていれば成功です。

おまけ

「tsconfig.json」で「”skipLibCheck”: true」を設定すればエラーは出なくなりますが、型チェックがされなくなるのは不安なため、「patch-package」を使う方法で対応しています。

おわりに

この度、React Native + Typescriptの環境を新規に作ろうとしてこのエラーに当たりました。

同様のトラブルがある方の解決の一助となればと思います。

コメント

タイトルとURLをコピーしました