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

July 2019Jonathan Gruber

During the last few 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 listed types look identical and should therefore obviously be compatible with each other. Of course TSType­Alias­Declaration from @babel/types should be assignable to TSType­Alias­Declaration! TypeScript, however, disagrees. It took me a while to figure out what is wrong.

Incompatible npm package versions

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, 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 verisons of @babel/types 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.

Another pitfall – Yarn’s 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.