NRWL NX library typescript ambient declaration files
Asked Answered
G

1

12

I have a basic setup in my new NX workspace

  • /apps/my-app (node type)
  • /libs/some-lib (node type)

Both created with nx cli commands: i.e. nx g @nrwl/node:lib some-lib --simpleModuleName=true

For library I wanted to use ambient declaration files (.d.ts). I added one in /libs/some-lib/src/types/index.d.ts, with content:

declare type MyCustomType = any;

As I understand, this file gets processed based on /libs/some-lib/tsconfig.lib.json file, but I also added direct reference to this file in /libs/some-lib/tsconfig.json:

{
    "extends": "../../../tsconfig.base.json",
    "files": [
        "src/types/index.d.ts"
    ],
    "include": [
        "src/types/**/*.d.ts"
    ],
    "references": [
        {
            "path": "./tsconfig.lib.json"
        },
        {
            "path": "./tsconfig.spec.json"
        }
    ]
}

My IDE is happy when I'm using this file inside lib's code, for example: /libs/some-lib/src/lib/file.ts

export const x: MyCustomType = 1;

But if I want to import this variable into my-app and I run it (nx serve my-app),

import { x } from '@my-workspace/some-lib';

I get an error from the compiler:

ERROR in libs/some-lib/src/lib/file.ts
TS2304: Cannot find name "MyCustomType".

So my question is, is there a way to use ambient declaration files inside libraries and not to get errors when running application that imports abstractions from this library?

I could create in the root folder shared types: *types/myCustomType.d.ts" and then include it in the application's and library's tsconfigs in files property, but I wan't to avoid it and keep types close to the code.

Another solution that works, but is ugly as hell is to add additional reference to the library in my-app's tsconfig file:

{
    "path": "../../libs/some-lib/tsconfig.json"
}

Result /apps/my-app/tsconfig.json:

{
      "extends": "../../tsconfig.base.json",
      "files": [],
      "include": [],
      "references": [
        {
          "path": "./tsconfig.app.json"
        },
        {
          "path": "./tsconfig.spec.json"
        },
        {
          "path": "../../libs/node/schedulers/tsconfig.json"
        }
      ]
}

Or create a tsconfig.json barrel: /libs/tsconfig.json ... and just reference relevant libraries there. my-app's tsconfig file would only need to reference this single file.

Gabler answered 15/11, 2021 at 14:55 Comment(0)
M
1

Create a root directory for all types types/ Create sub-directories for apps and libs

  • types/lib-a/
  • types/lib-b/
  • types/app-a/

No need to add these type to the tsconfig.base.json. Revert all your tsconfig files to the defaults and then add the typeRoots in each library and applications' tsconfig.json files. Also include the typeRoots for the libraries it depends on.

  1. libs/lib-a/tsconfig.lib.json
{
    ...
    "compilerOptions": {
        "typeRoots": ["../../../types/lib-a/"]
    },
    ...
}
  1. libs/lib-b/tsconfig.lib.json
{
    ...
    "compilerOptions": {
        "typeRoots": ["../../../types/lib-b/"]
    },
    ...
}
  1. apps/app-a/tsconfig.app.json also add the dependent libraries' types here
{
    ...
    "compilerOptions": {
        "typeRoots": [
            "../../../types/lib-a/",
            "../../../types/app-a/"
        ]
    },
    ...
}
Mulkey answered 5/12, 2022 at 0:15 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.