Search code examples
typescriptyarnpkgtsconfigmonorepo

How do I use the tsconfig.json "types" field when in a monorepo?


Part 1 - An example of using the "types" field

TypeScript library A provides type definitions in addition to its "normal" exports, like this:

declare global {
  function someGlobalFunction(): void;
}

Library B consumes the type definitions of library A. Thus, in the tsconfig.json of library B, we put:

"types": ["library-a"],
  • By doing this, using someGlobalFunction no longer results in a compiler error.
  • Obviously, this requires "library-a" to be listed as a dependency in the package.json of library B.
  • Obviously, it also requires that "library-a" is installed and available in the "node_modules" subdirectory.

Part 2 - A Monorepo

I have a TypeScript monorepo. (It is using NX as the monorepo tool and Yarn as the package manager, but that probably doesn't matter, as this question would apply to any kind of TypeScript monorepo.)

If library A and library B are both in my monorepo, how do I replicate the setup from part 1?

To start with, the monorepo uses the paths field in the tsconfig.json file in order for packages to import each other without having to actually install them. This is trivial to do and works well. However, it breaks down if we use the types field, as paths and types do not seem to be programmed to work together. Specifically:

  • If I try specifying "types": ["library-a"] like before, TypeScript can't find it, saying library-a is not found.
  • If I try adding a typeRoots field to point to the correct "dist" directory, then I can get past that error, but still get a bunch of "not found" errors for all of the individual symbols.
  • If I just install library-a directly, then everything works, but doing that defeats the whole point of using a monorepo in the first place.

What is the correct way for a package to import the types from another package in a monorepo?

I can provide a minimal reprex repo to illustrate the problem, if needed.


Solution

  • I managed to achieve your desired result using this in library-b's tsconfig.json:

    {
      "compilerOptions": {
        "types": ["../library-a"],
        "typeRoots": ["../library-a/types"],
        "paths": {
          "library-a": ["../library-a/index.ts"]
        }
      }
    }
    

    See https://github.com/Maxim-Mazurok/ts-2libs for full reproduction.

    In case if I got it wrong - please fork it or provide your own repro.