Handling type declarations clash in Typescript
A short story about compilation error based on type declarations with the same names
I want to share one interesting case with Typescript modules resolution, which I recently encountered.
We are talking about the application on React and Typescript, currently, we in our company use ts-loader, but earlier we also used awesome-typescript-loader. The problem arose in both cases.
It happened so that in our project two runners are used for tests: Jest and Mocha. Jest drives our unit tests, and Mocha starts programmatically from the code for integration tests on Puppeteer.
Both runners have their own @types/xxx
packages installed in devDependencies:
"@types/jest": "20.0.6",
"@types/mocha": "5.2.5",
"jest": "22.4.3",
"mocha": "5.2.0"
As a result of the compilation, I received the following error:
Subsequent variable declarations must have the same type.
After some googling, I found that this error is quite common. Often it happens that two packages of type definitions define global types with the same names: as a result, we have a clash of definitions and compiler complains about it.
There are other reasons, different from my case, for this situation:
- you may have installed the wrong version of @types/xxx
for your package and you need to upgrade it;
- you may have installed the same package twice into different folders within node_modules
.
Unfortunately, my problem wasn’t related to the wrong version of a package: I couldn’t solve it with different ways suggested in Github issues. These things didn’t work for me:
- point out mocha
or jest
in the "types"
array of the tsconfig.json
file;
- set the "paths"
for the one or both packages in the tsconfig.json
;
- "exclude"
these packages in tsconfig.json
options.
One thing worked out: skipLibCheck
flag that you can set to the compilerOptions in tsconfig.json
. It solves the problem but it looks a bit hacky and I don’t like to skip any checks that are set in Typescript by default. My tech lead also didn’t like the idea of skipping type declarations check, so I had to invent something new.
I thought I have tried everything and failed but this advice in one issue saved me. In the project root, I created a folder overrides
where I put 2 folders: jest
and mocha
. As I encountered the error with Mocha types, I copied the index.d.ts
file from the node_modules/@types/mocha
folder and put it in the newly created overrides/mocha
directory. In the overrides/jest
folder I created an empty index.d.ts.
Then I added one new option to my tsconfig.json
:
{
"compilerOptions": {
"typeRoots": ["overrides", "node_modules/@types"]
}
}
It worked! Now I can build the project without compilation errors and avoid skipLibCheck
flag as an undesired thing for our config.
Here is the whole tsconfig.json
:
Typescript version used for the project: 3.3.0-rc
Jest @types/jest
version: 20.0.6
Mocha @types.mocha
version: 5.2.5
I hope this article would be useful for your projects but I also hope you won’t face errors like these very often 😉.