question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

VSCode TypeScript project references resolve of duplicate files

See original GitHub issue

Bug Report

🔎 Search Terms

VSCode, tsconfig ,project references

🕗 Version & Regression Information

  • TypeScript Version: 4.1.0-dev.20201020 (4.1.0-dev.20201019 works well)
  • VS Code Version: 1.64.2 (Universal)
  • OS Version: Darwin x64 21.2.0

⏯ Example repo

https://github.com/xiaoxiangmoe/typescript-project-reference-demo.git

💻 Code

// tsconfig.json

{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.test.json"
    },
  ]
}

// tsconfig.app.json

{
  "include": ["src/**/*"],
  "exclude": ["src/**/__tests__/*"],
  "compilerOptions": {
    "moduleResolution": "Node",
    "composite": true,
    "target": "ESNext",
    "noEmit": true,
    "strict": true,
    "lib": ["DOM", "ESNext"],
    "types": []
  }
}

// tsconfig.test.json

{
  "extends": "./tsconfig.app.json",
  "exclude": [],
  "compilerOptions": {
    "types": ["node"]
  }
}

// src/components/Foo.ts

export type FooProps = { a: number };
export function Foo(props: FooProps) {
  return null;
}
/**
 * this file is included in both `tsconfig.app.json` and `tsconfig.test.json`
 * 
 * So we should follow the order of `references` in `tsconfig.json`
 * 
 * `tsconfig.app.json` comes before `tsconfig.test.json`, so we should use config file `tsconfig.app.json` in vscode
 * 
 */
const cwd = process.cwd()

🙁 Actual behavior

I think const cwd = process.cwd() should has an Error.

Because file src/components/Foo.ts are included in tsconfig.app.json. So it has not include type @types/node.

🙂 Expected behavior

const cwd = process.cwd() has no Error.

File src/components/Foo.ts is included in both tsconfig.app.json and tsconfig.test.json. VSCode search references field and use the last item of references —— tsconfig.test.json. So it has no error.

I think we should use first reference. I remember that earlier versions of vscode did this too. I want to know why VSCode/TS change it to use last reference?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
sodateacommented, Mar 7, 2022

this is the first complaint we’ve seen of it

Maybe because it’s a subtle problem that many users won’t notice? Nevertheless, this doesn’t imply the issue isn’t common.

We can work around this issue in the command line. But there’s no easy way to fix this in the IDE/editor.

If a file is in multiple projects like this, the one we choose to load it in is arbitrary

Why? This makes it impossible to support the following use case:

  • src/Foo.ts and src/Bar.ts are front-end modules that are supposed to run in browsers;
  • src/__tests__/Foo.spec.ts is a Jest (or Vitest) spec module that imports and tests against src/Foo.ts. The test environment is Node.js with JSDOM.
  • No corresponding spec for src/Bar.ts
  • To differentiate the 2 environments, we need 2 different sets of tsconfigs:
    1. src/Bar.ts MUST be picked up by a tsconfig.app.json, which excludes the Node.js types;
    2. src/__tests__/Foo.spec.ts MUST be picked up by a tsconfig.test.json, which includes the Node.js types.
    3. Because src/Foo.ts is used in both the frontend project and the test project, it has to be included in both projects’ tsconfigs. It would be type-checked twice in CI, to make sure it is both runnable in browsers and testable in Node.js.

In this scenario, we need src/* to be picked up by tsconfig.app.json by default, src/**/__tests__/* to be picked up by tsconfig.test.json by default.

Modules like src/Foo.ts should only be picked up by the tsconfig.test.json only when TypeScript parses src/__tests__/Foo.spec.ts and encounters an explicit import of src/Foo.ts. But as tsconfig only supports simple glob patterns in include and exclude, we have to specify src/* in tsconfig.test.json too.

So to prevent src/Bar.ts from accidentally picked up by tsconfig.test.json, we need a deterministic order of references loading, be it left-to-right or right-to-left.


Similar use cases are also very common in server-side-rendered apps with many modules to be used in both the browser and Node.js context.

1reaction
sodateacommented, Mar 7, 2022

To solve the issue, I propose that:

  1. TypeScript should at least document the order of loading references;
  2. If possible, would you accept a PR that reverts the behavior to pre-4.1? Because:
    1. It was more intuitive IMHO.
    2. Several downstream libraries still depend on that behavior.
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to solve TS "Duplicate identifier" clash with VSCode ...
I have the following type in my .ts file: type Permissions = 'admin' | 'user' | 'manager'. And VSCode shows me the following...
Read more >
Solution Explorer showing duplicate files
Opening a simple Dotnet Core project, the solution explorer is showing duplicated files, where are are only one file in the folder.
Read more >
Refactoring source code in Visual Studio Code
Refactorings are provided by a language service and VS Code has built-in support for TypeScript and JavaScript refactoring through the TypeScript language ...
Read more >
Working with JavaScript in Visual Studio Code
It is possible to have mixed TypeScript and JavaScript projects. To start migrating to TypeScript, rename your jsconfig.json file to tsconfig.json and set...
Read more >
CSS, SCSS, and Less support in Visual Studio Code
Go to Declaration and Find References. This is supported for Sass and Less variables in the same file. CSS variables per the draft...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found