LoginSignup
1
1

More than 1 year has passed since last update.

npm install / yarn add したら tsc が通らなくなった話

Posted at

React のカスタムフックをテストするために @testing-library/react-hooks をインストールしました。
そして tsc を実行すると types 周りがコケる現象が発生しました。

$ tsc --noEmit
node_modules/@testing-library/react-hooks/node_modules/@types/react/index.d.ts(3092,14): error TS2300: Duplicate identifier 'LibraryManagedAttributes'.
node_modules/@testing-library/react-hooks/node_modules/@types/react/index.d.ts(3103,13): error TS2717: Subsequent property declarations must have the same type.  Property 'a' must be of type 'DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>', but here has type 'DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>'.
...

本記事はこのエラーの考察と解決方法を記録したものです。

TL;DR

違うバージョンの @types/* が解決されたので

  • npm なら npm dedupe && npm install
  • yarn なら npx yarn-deduplicate && yarn install1

を実行して一個にまとめること。

発生経緯

説明用のサンプルを公式から拝借しました。
こんな感じにテストケースを書いています。

useCounter.spec.ts
import { renderHook, act } from '@testing-library/react-hooks'
import useCounter from './useCounter'

test('should increment counter', () => {
  const { result } = renderHook(() => useCounter())

  act(() => {
    result.current.increment()
  })

  expect(result.current.count).toBe(1)
})

このテストケースを jest から実行するときはなんの問題もありませんが、tsc を実行したときだけコケました。

問題の原因

プロジェクトの構造はこんな感じにしています。

├── README.md 
├── src
│   ├── components   <- React のコンポーネントを置くディレクトリ
│   │   └── MyComponent.ts
│   └── models       <- カスタムフックとかを置くディレクトリ
│       ├── useCounter.ts
│       ├── useCounter.spec.ts

tests フォルダを別に切り出すのではなく、テストファイルをテストしたいもののすぐ近くに置く構成にしています。
そして tsconfig.jsoninclude フィールドに src 以下を追加すると

tsconfig
{
  "include": [
    "src/**/*"
  ]
}

tsc を実行する時ファイルパスを指定しなくてもOKになります。

$ tsc --noEmit

この構成にしているため、tsc の実行時は src 以下のソースファイルとテストファイルの両方を見るようになっています。

今回のエラーメッセージ

$ tsc --noEmit
node_modules/@testing-library/react-hooks/node_modules/@types/react/index.d.ts(3092,14): error TS2300: Duplicate identifier 'LibraryManagedAttributes'.
node_modules/@testing-library/react-hooks/node_modules/@types/react/index.d.ts(3103,13): error TS2717: Subsequent property declarations must have the same type.  Property 'a' must be of type 'DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>', but here has type 'DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>'.
...

はずばり @types/react/index.d.ts を読み込んだ時、型が二重定義されていたため起こったエラーです。

型の二重定義

node_modules/@testing-library/react-hooks/node_modules/@types/react/index.d.ts を見ればわかりますが、
スクリーンショット 2021-10-11 033915.png
global 以下に定義されたものがコンフリクトしています。
これが起こったのは @types/react が複数存在しているためです。

$ yarn list @types/react
yarn list v1.22.11
warning Filtering by arguments is deprecated. Please use the pattern option instead.
├─ @testing-library/react-hooks@7.0.2
│  └─ @types/react@17.0.27
└─ @types/react@17.0.15

プロジェクトからは @types/react@17.0.15 を直接利用していますが、
@testing-library/react-hooks@7.0.2 からは違うバージョンの @types/react@17.0.27 が間接的に import されています。
tsc を実行するときは、プロジェクトから直接依存している types は自動的に読み込まれますが、テストファイルの

import { renderHook, act } from '@testing-library/react-hooks'

のこれも @testing-library/react-hooks 内の @types/react@17.0.27 を読み込んでいます。
この2つの @types/react は同時に global に型を定義しているため、同じ名前の型が二重定義されてコンフリクトしています。

複数のnode_modules

npm / yarn を利用するプロジェクトはこのように、node_modules 以下にさらに node_modules を保つことができます。

./node_modules
./node_modules/make-dir/node_modules
./node_modules/npm/node_modules/resolve/test/shadowed_core/node_modules
./node_modules/eslint-plugin-react/node_modules/resolve/test/resolver/symlinked/_/node_modules

例えば ab から複数のライブラリのから依存されているライブラリ c はもし同じバージョンに解決できたら、共通でルート以下の ./node_modules にその共用のライブラリを置かれますが、
同じバージョンに解決されなかった場合はそれぞれのディレクトリ以下

  • ./node_modules/a/node_modules/c
  • ./node_modules/b/node_modules/c

に置くことになります。

今回の @testing-library/react-hooks でいうと、実は "@types/react": ">=16.9.0",満たせば問題ないので、プロジェクトの @types/react と同じバージョンに解決することができたはずです。

解決方法

ここに解決方法が書かれています。

かいつまんで言うと、

  • npm なら npm dedupe && npm install
  • yarn なら npx yarn-deduplicate && yarn install1

を実行したら、2つバージョンが違った @types/react を一個に解決できて、今回のエラーを修正できました。

$ yarn list @types/react
yarn list v1.22.11
warning Filtering by arguments is deprecated. Please use the pattern option instead.
└─ @types/react@17.0.27

  1. なぜか yarn dedupe だと効かなくて npx yarn-deduplicate にしないといけないようです 

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