TypeScript – When a data type is not assignable to itself (TS2345)

July 2019Jonathan Gruber

During the last months, when I developed a Babel plugin with TypeScript, I encountered strange errors like the following after updating the npm packages several times:

src/plugin/visitors/flow.ts:59:22 - error TS2345: Argument of type 'TSTypeAliasDeclaration' is not assignable to parameter of type 'AnyTypeAnnotation | ArgumentPlaceholder | ... 222 more ... | NodePath<...>'.
  Type 'import("<path>/node_modules/@babel/types/lib/index").TSTypeAliasDeclaration' is not assignable to type 'babel.types.TSTypeAliasDeclaration'.

59     path.replaceWith(convertDeclareOpaqueType(node, state));
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

At first glance, the types that cause the error look identical and should therefore obviously be compatible with each other. Of course TSTypeAliasDeclaration from @babel/types should be assignable to itself! TypeScript, however, disagrees. It took me a while to figure out what is wrong.

The issue

Recently I read in the React documentation that several installed versions of React can break the new hooks feature. That put me on the right track. After executing the following command to list all the , it becomes clear what is going wrong:

npm ls @babel/types

One of the dependencies set a different version range of @babel/types. Consequently, two (or more) incompatible versions of this package were installed and lead to above TypeScript error. Thankfully, Yarn offers a feature to resolve such conflicts called selective version resolutions. This way you can enforce that all installed npm packages must use a specific version of another dependency. Simply add the following to your package.json:

// package.json
{
  "resolutions": {
    "@babel/types": "^7.5.0"
  }
}

npm does not seem to have a comparable feature at the moment.

yarn package cache

Another problem might be Yarn’s cache. When packages are installed with Yarn, they are retrieved from its cache if possible. So if an older versions of e.g. @babel/types has been cached that matches given version range of a dependency, problems like the error above can occur.

To purge Yarn’s cache execute the following:

yarn cache clean

Afterward, delete your node_modules/ directory and reinstall the npm packages.