Home > database >  How can I make VS Code recognize typescript declarations between mono-repo packages?
How can I make VS Code recognize typescript declarations between mono-repo packages?

Time:11-25

I have a mono-repo project configured with an isolated library package (TS only) and another web UI package (TS React).

I am importing the compiled library package from the consumer (web UI) package. To do so, I am using yarn to link the packages and parcel to generate the library package's distribution files.

Parcel is automatically generating a d.ts file in the library package's dist folder.

I am using the VS Code as IDE and when I open the consumer packages file that imports the library and make use of it, the VS Code is not recognizing the types declared in the library package's d.ts file.

This is the packages' structure:

rootPackage
|- library
|- web-ui

In the library package, I have a types.ts file and an index.ts file. There is only a single type being exported:

export type ParamType = "a" | "b" | "c";

I'm using parcel watch on this package to automatically refresh the dist files when something is changed.

Parcel is generating the main.d.ts file just fine and this file is being referenced by the package.json's types attribute.

When I try to use this ParamType type by the web-ui package's code, I got the following IDE error highlighting in the type:

Cannot find name 'ParamType'.ts(2304)

When I run parcel in the web-ui package, it compiles just fine and the browser is loaded with no problems/warnings.

I think it's a problem related exclusively to the VS Code and I'm not sure how to fix it.


Edit 1

I've created a public repository on GitHub to demonstrate the issue. If you know how to fix it, feel free to create a pull request, it would be very helpful.

CodePudding user response:

From your example repo, the root of your library package looks like this:

/shared/lib/src/index.ts

import { ParamType } from "./types";

const Library = {
  typedParamMethod(param: ParamType) {
    console.log(param);
  },
};

export default Library;

And the way you're consuming the library package in your web-ui package is is like this:

/ui/web/src/App.tsx

import React from 'react';
import Library from 'library';

function App() {
  React.useEffect(() => {
    const typedParam: ParamType = 'b'; // VSCode and tsc throw the error "Cannot find name 'ParamType'." 
    Library.typedParamMethod(typedParam);
  }, []);

  return (
    <div className="web-ui">Web UI</div>
  );
}

export default App;

The problem is that you are neither exporting ParamType from to root of your library package, nor importing it into your web-ui package. Modern JavaScript and Typescript modules are isolated from each other - the import { ParamType } from "./types" line in your library package root makes ParamType available in that file, but it doesn't affect (or pollute) the global namespace of something that happens to import something else (e.g. the default export) from the library package.

To solve the problem, add this line to the library package root (e.g. /shared/lib/src/index.ts):

export { ParamType } from "./types.ts";

And then modify the import from your web-ui package (in /ui/web/src/App.tsx to this:

import Library, { ParamType } from 'library';

(The problem and solution are unrelated to VSCode - anything that tries typecheck the web-ui package will emit the same error, without these changes)

  • Related