Import syntax with TypeScript project references

Viewed 851

What is the proper way to import modules from another sub-project in TypeScript?

I have this project structure:

myproject/
  tsconfig.json
  tsconfig-base.json
  src/
    tsconfig.json
    core/
      A.ts
      B.ts
    extra/
      C.ts
      D.ts
  test/
    tsconfig.json
    test.ts
  built/
    core/...
    extra/...
    test/...

tsconfig-base.json:

{
  "compilerOptions": {
    "target": "ES2018",
    "module": "commonjs",
    "declaration": true,
    "outDir": "built",
    "composite": true,
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  }
}

tsconfig.json:

{
    "files": [],
    "includes": [],
    "references": [
        { "path" : "./src" }, 
        { "path" : "./test" }
    ]
}

src/tsconfig.json:

{
    "include": ["**/*"],
    "extends": "../tsconfig-base.json",
    "compilerOptions": {
        "rootDir": "."
    }
}

test/tsconfig.json:

{
    "extends" : "../tsconfig-base.json",
    "include" : ["*"],
    "references": [
        { "path": "../src" }
    ],
    "compilerOptions" : {
        "outDir": "../built/test",
        "rootDir": "."
    }
}

In test/test.ts, I do:

import { Thing } from "../core/A"

Because this thread suggests that modules should be imported "from wherever they end up" when using outDir, I would expect the above to work (because built/core/A.js is relative to built/test/test.js via the specified path). Similarly, the TypeScript docs on project references show an example with similar structure with an import omitting "src" as above.

Instead, I get:

test/test.ts:1:28 - error TS2307: Cannot find module '../core/A'.

1 import { Thing } from "../core/A"

Why is this? How does TypeScript search for imports when using project references? (Note that in this case, it would be untidy to be forced to include "src/" in all the import paths).

What is the proper way to accommodate the project structure above?

Thanks!

1 Answers

By updating file src/tsconfig.json:

{
    "include": [
        "**/*"
    ],
    "extends": "../tsconfig-base.json",
    "compilerOptions": {
        "outDir": "../built/src",
        "rootDir": "."
    }
}

And run:

$./src  tsc
$./test tsc

I'll have a build structure like:

- built/
  - src/
    - core/ 
      - A.d.ts
      - A.js
  - test/
    - test.d.ts
    - test.js

And run:

$./myproject node built/test/test.js

It will work as expected. Doesn't it?

Related