Working with multiple tsconfig.json files in Visual Studio Code for a TypeScript project

Initially, I acknowledge that there are numerous similar questions out there, but none of them seem to provide a solution to my specific issue...

Here's the setup of my ElectronJS project created with Nextron and its file structure looks something like this:

├── main/
│   └──...
├── renderer/
│   ├── src/
│   │   └── index.ts
│   ├── td/
│   │   └── env.d.ts
│   ├── ...
│   └── tsconfig.json
├── tsconfig.json
└──...

The content within the root tsconfig.json file is as follows:

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "moduleResolution": "node",
    "jsx": "preserve",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "resolveJsonModule": true,
    "isolatedModules": true
  },
  "include": ["renderer/next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules", "renderer/next.config.js", "app", "dist"]
}

Meanwhile, the content in renderer/tsconfig.json is:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@src": ["src"],
      "@src/*": ["src/*"]
    }
  },
  "include": ["./td/*.ts"]
}

Everything runs smoothly when I execute the project via

npm run dev

or

npm run build

However, in vs-code, I'm encountering errors (within files in the renderer directory) regarding constants and other declarations not being recognized (even though they are defined in /renderer/td/env.d.ts)

In essence, I can continue working despite seeing IDE errors, knowing that the build process will function properly (meaning I can retrieve values from declared environment constants and access specified path aliases), but it's still quite frustrating...

Any suggestions on how to enable vs-code to accurately detect the included files?

As a reference, the content of /renderer/ts/env/d/ts resembles:

/** Env constant set to (package.json).name */
declare const PACKAGE_NAME: string;
/** Env constant set to (package.json).version */
declare const PACKAGE_VERSION: string;
/** Env constant set to the build ID */
declare const BUILD_ID: string;
/** Env constant set to the git commit hash */
declare const COMMIT_HASH: string;
/** Env constant set to the 7 first characters of the git commit hash */
declare const COMMIT_HASH_SHORT: string;
/** Env constant set to `true` for server-side code usage, or `false` for client-side delivery */
declare const IS_SERVER: boolean;
/** Env constant set to `true` for production build, or `false` for development */
declare const IS_PRODUCTION: boolean;

This essentially declares the environment variables set during build time by webpack on NextJS

Edit: Uploading a repository with the basic configuration to replicate this issue: https://github.com/danikaze/vscode-multi-tsconfig

Answer №1

Not too long ago, I ran into a similar issue while working on my Vue JS project at my company. Our project setup involves a mono-repo structure, which means we had a main tsconfig.json file at the root level, as well as individual tsconfig.json files for each child app.

The problem arose when the Vetur extension in VS Code only recognized the root level tsconfig.json, ignoring the app-specific ones. This led to errors in intellisense for me.

I found a workaround that solved this issue, detailed in the link below. You need to create a Multi-root workspace. Add both the root directory and the child app's renderer directory to the multi-root workspace, with the renderer directory listed first in the .code-workspace file under folders.

Your

{name of your workspace}.code-workspace
file should resemble the following code snippet.

{
  "folders": [
     {
       "name": "your subdirectory app",
       "path": "./renderer"
     },
     {
       "name": "your root directory",
       "path": "."
     }
  ]
}
    

By following these steps, you should enable VS Code to recognize the tsconfig file from your subdirectory.

Check out this Github Issue

Answer №2

To resolve this problem, I found that including a multi-root directive in .vscode/settings.json was the solution.

For example:

{
  "eslint.workingDirectories": [
    "project1",
    "project2",
    "project3",
  ]
}

Answer №3

After encountering a challenge, I decided to bring it up on GitHub for discussion. After diving deep into the issue and even creating a second thread, it turns out that the root cause was actually something different than what was initially thought.

The issue stemmed from attempting to import external data from an included file, which is not compatible with the specifications.

Due to the presence of an import statement in `env.d.ts`, the file is treated as a module (module variables are isolated and must be explicitly imported instead of being part of the global scope).

To address this, one can define `PACKAGE_NAME` explicitly in the global scope:

Check out the official solution thread here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Determine the output of a function based on the structure of the input parameter by mapping through a complex nested object

Trying to implement some intricate typing for a project I'm developing, and wondering if it's achievable with TypesScript. The project in question is a form generator based on schemas and promises, using Vue and TS. It handles UI rendering, vali ...

Loading custom components dynamically in Angular with SVG: a how-to guide

Looking for a way to dynamically load SVG items with ease. The items needed are quite simple. Here's a basic template: <svg:rect [attr.x]="x" [attr.y]="y" width="10" height="10" /> Component Class Example: export class DraggableSvgItemCompon ...

Ways to avoid using a specific type in TypeScript

Imagine having a class that wraps around a value like this: class Data<T> { constructor(public val: T){} set(newVal: T) { this.val = newVal; } } const a = new Data('hello'); a.set('world'); // typeof a --> Primitiv ...

What is the process for adding new methods to a predefined data type?

Currently, I am utilizing Webpack's require.context in order to eliminate redundancy while importing multiple pages. However, TypeScript is throwing an error stating that Property 'context' does not exist on type 'NodeRequire'.. I ...

How can I retrieve the SID received in a different tab using MSAL.js?

I have successfully integrated MSAL into a client-side library, and things are going smoothly so far. My next goal is to enable Single Sign-On (SSO) by following the instructions provided in the documentation at https://learn.microsoft.com/en-us/azure/act ...

What is the best way to globally incorporate tether or any other feature in my Meteor 1.3 TypeScript project?

I've been working hard to get my ng2-prototype up and running in a meteor1.3 environment. Previously, I was using webpack to build the prototype and utilized a provide plugin to make jQuery and Tether available during module building: plugins: [ ne ...

The interaction between Nextjs router and useEffect resulting in unintended re-rendering

I'm currently facing a challenge with Next.js's next/navigation router. In my component, I have a series of useEffects implemented. Strangely, when I call router.replace, one of the effects runs twice or even infinitely in some cases. As a result ...

Transitioning to TypeScript: Why won't my function get identified?

I am in the process of transitioning a functional JavaScript project to TypeScript. The project incorporates nightwatch.js Below is my primary test class: declare function require(path: string): any; import * as dotenv from "dotenv"; import signinPage = ...

Combining files/namespaces/modules in Typescript: How to do it?

Even though I believe the solution may be simple, understanding how to merge enums across multiple files is eluding me when reading through the documentation. // a.ts enum Color{ RED, BLUE } // b.ts enum Day{ MONDAY, TUESDAY } // c ...

Is it possible to apply JavaScript object destructuring but make changes to certain values before assigning them to a new object?

After receiving movie data from an api, I am currently manually creating a new object with a subset of properties and modified values. Is there a more efficient way to achieve this using javascript/typescript object destructuring syntax? I specifically wa ...

Steps to resolve the issue of MatCardComponent not being detected despite being imported within the module

I am encountering an issue with my Angular nrwl nx project that includes Bootstrap 5 and Angular Material. Within a library, I have a dashboard component where I import the MatCardModule. However, when trying to use it inside the DashboardComponent, I rece ...

Troubleshooting a Deployment Problem in Azure timerTrigger Function with Service Bus Integration

I've been developing an Azure Function that utilizes a timer trigger and interacts with Azure Service Bus. Initially, the function deploys successfully when it only contains the timer trigger code. import { app, InvocationContext, Timer } from "@ ...

Troubleshooting issue with TypeScript: Union types not functioning correctly when mapping object values

When it comes to mapping object values with all primitive types, the process is quite straightforward: type ObjectOf<T> = { [k: string]: T }; type MapObj<Obj extends ObjectOf<any>> = { [K in keyof Obj]: Obj[K] extends string ? Obj[K] : ...

What could be the reason behind my Heroku app suddenly crashing without any visible errors?

After successfully starting the Nest application, about 50 seconds later it transitions from 'starting' to 'crashed'. The last log entry before the crash is a console log indicating the port number. View Heroku logs after successful bui ...

Tips for arranging TypeScript AST nodes and generating a TypeScript file as the final result

My objective is to reorganize the code in a way that sorts the link(foo) value based on the string text: import Text from '~/text.js' export default function rule(text: Text) { // Sorting rules alphabetically } Although I have made some progr ...

Is there a way to skip importing React from the test file when using Jest?

I'm currently using testing-library with React Within my test file, I have the following setup: import { render, screen } from '@testing-library/react' import React from 'react' // It would be ideal to avoid including this in each ...

When attempting to execute my script, I encountered an error message stating that "TypeError: puppeteer.use(...) is not

Here is the current code that I've been working on. After switching it to a new folder, I encountered an error that wasn't present before. I made sure to reinstall all the necessary modules in the package.json file, but the issue persists. Is the ...

Combining the power of Visual Studio Code with NodeJs allows for seamless detection of missing package namespaces

Recently, I've encountered a frustrating problem. It occurs when: I create a new Node project without any installed modules I use import '' and press ctrl+space between the brackets, resulting in unnecessary inferred namespaces. Alth ...

Leveraging Express Mergeparams in TypeScript

I've run into an issue while working on my small project in Typescript. The problem arises when I attempt to nest my router, as Typescript doesn't seem to acknowledge the parent's parameter. Within the "child" file, I have the following cod ...

Delete an entry in a singular mapping in a one-to-one connection [TypeORM]

Is there a way to remove an index from a one-to-one relationship in TypeORM? @OneToOne(() => Customer, { cascade: true }) @JoinColumn({ name: 'customer', referencedColumnName: 'uid' }) customer: Customer I searched the d ...