James
James

Reputation: 774

Lerna, yarn, and Typescript: Cannot find module or its corresponding type declarations

I have a lerna + yarn workspaces monorepo, with independent versioning. I'm having trouble importing a package in its sibling.

I have two packages, one of which should depend on the other, as illustrated below:

(root)
  |--packages
       |--money
       |--money-standard-units
            |--{deps. on money}

Inside of money-standard-deps, I try to import an exported member of money but I'm unable to do so; I get the following message:

TS2307: Cannot find module 'money' or its corresponding type declarations.

I know this issue can be resolved by adding money to the paths array of money-standard-libs's tsconfig, but I want to depend on the built package as these will be published seperately. I want this to effectively work as-if it's two seperate repos.

I've created a demo repo.

Upvotes: 16

Views: 20649

Answers (1)

Josh Aguilar
Josh Aguilar

Reputation: 2271

You will need to configure your typescript project to generate type declaration *.d.ts files if it is going to be used as a dependency of another typescript project. To do this, you will need to set the compilerOptions.declaration property of your tsconfig to true. You can do this in your tsconfig-common.json file.

For example (tsconfig-common.json):

{
  ...
  "declaration": true
  ...
}

Additionally, in the same way you specify a main property in your package.json file to identify the entry file for your package you will also need to specify a types property to specify where your type declaration file is located. You need to do this for every package in your monorepo.

For example (package.json):

{
  "name": "@somescope/money",
  ...
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  ...
}

Also, I noticed that you do a default export in your monetary-unit module, but then do a named import for it in the uses-money module.

You will need to change the monetary-unit module to use a named export on the class if you intend to refer to it using a named import.

Example (monetary-unit.ts):

// Remove the default keyword
export class MonetaryUnit {
  constructor(
    readonly value: number,
    readonly name: string,
  ) {}
}

Upvotes: 35

Related Questions