Generating TypeScript declarations for legacy CommonJS dependencies with the correct "module" setting

One of my challenges involves creating type declarations for outdated dependencies that produce CJS modules and lack typings. An example is the aabb-3d module (although this issue isn't specific to that particular module).

To generate the declaration, I typically use a command like this:

tsc node_modules/aabb-3d/index.js 
    --allowJs 
    --declaration 
    --emitDeclarationOnly 
    --outFile types/aabb-3d/index.d.ts

The generated declaration file looks something like this:

declare module "index" {
    export = AABB;
    function AABB(pos: any, vec: any): AABB;
    //...

However, my code editor doesn't recognize these typings because it expects the declaration to reference the module as aabb-3d, not index.

If I manually update the generated d.ts file to reflect the correct module name, my editor functions properly and provides accurate code hints for the older module. How can I ensure that tsc generates correct declaration files automatically?

Answer №1

After investigating TypeScript's source code, it seems that there is no straightforward method to alter the generation of the declare module line. However, there is a workaround to prevent its generation entirely. The reason you are receiving an ambient external module declaration (declare module) is because you are utilizing --outFile instead of --outDir. To create the same types/aabb-3d/index.ts file as an ES-style module declaration without using declare module, follow these steps:

tsc node_modules/aabb-3d/index.js 
    --allowJs 
    --declaration 
    --emitDeclarationOnly 
    --outDir types/aabb-3d

To enable TypeScript to recognize the ES-style module declarations within the types directory, include the following configuration in your project's tsconfig.json:

{
    ...
    "compilerOptions": {
        ...
        "typeRoots": [
            "./types",
            "./node_modules/@types"
        ],
        "baseUrl": "./",
        "paths": {
            "*": [
                "./types/*",
                "*"
            ]
        }
        ...
    }
    ...
}

With this setup, you can now use import aabb3d from 'aabb-3d' in your code with the proper typings generated by tsc.

In cases where a package's "main" file is not named

index.js</code and consequently the generated declarations do not have the name <code>index.d.ts
, you will need to add a package.json file inside the types/$package directory to specify the correct file. For instance, if the main file is named main.js resulting in the declarations file being main.d.ts, the contents of the package.json should be as follows:

{
    "types": "main.d.ts"
}

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

Can I modify the cookie domain for NestJS SessionModule on a per-request basis?

I am currently using NestJS with SessionModule to handle user cookies successfully. However, I have a requirement to override the domain name for certain requests. I am uncertain about how to achieve this within NestJS, as the domain setting appears to b ...

Is there an option for keyPrefix in i18next?

For my current project, I am utilizing both i18next and react-i18next. One useful feature of using the useTranslation hook from react-i18next is the "keyPrefix" option, which helps in reducing code duplication. However, there are instances where I need to ...

Typescript not being transpiled by Webpack

As I set out to create a basic website, I opted to utilize webpack for packaging. TypeScript and SASS were my choice of tools due to their familiarity from daily use. Following the documentation at https://webpack.js.org, I encountered issues with loaders ...

The class 'GeoJSON' is mistakenly extending the base class 'FeatureGroup'

Encountering an error message in one of my projects: test/node_modules/@types/leaflet/index.d.ts(856,11): error TS2415: Class 'GeoJSON' incorrectly extends base class 'FeatureGroup'. Types of property 'setStyle' are incompa ...

Retrieving user input from one component to be used in another component in Angular

I'm currently working on a structure that involves a navbar component and a form component https://i.stack.imgur.com/nPRLO.png Initially, I have a navbar component where I load user data using an ID stored in the session. In the right side component ...

Dealing with asynchronous operations in a pipeline with fp-ts

I'm currently exploring fp-ts and have been contemplating how to restructure my functions in order to steer clear of nested folds. While many online examples showcase a clean invocation of the pipe function, I am struggling to eliminate the nested fol ...

Ways to showcase information based on the chosen option?

Is there a way to display data based on the selected value in a more efficient manner? Currently, when clicking on a value from the list on the left side, new data is added next to the existing data. However, I would like the new data to replace the existi ...

Issue with executing a server-side function in a Next.js application

I'm encountering an issue with my Next app. I have a method in my ArticleService class that retrieves all articles from my SQL database. async getArticles(): Promise<IArticle[] | ServiceError> { try { const reqArticles = await sql< ...

'value' is connected to every single hook

Every time I try to save my work using any hook, the 'value' field changes automatically. This has been causing me a great deal of stress. I would be extremely grateful if someone could assist me with this issue. click here for image description ...

Fixing the "Cannot find name" error by targeting ES6 in the tsconfig.json file

I recently started learning AngularJS through a tutorial. The code repository for the tutorial can be accessed at this link. However, upon running npm start using the exact code provided in the tutorial, I encountered the following error: Various TS2304 e ...

Trouble accessing nested components in Angular CLI beyond the first level of components

I'm diving into Angular CLI for the first time and trying to recreate a previous web project of mine. I've managed to nest and display components inside the root component successfully, but after that, I'm facing issues referencing any compo ...

What are the steps to correct a missing property in an established type?

Currently, I am in the process of converting an existing Node.js + express application from plain JS to TypeScript. Although I understand why I am encountering this error, I am unsure about the correct approach to resolve it. The type "Request" is coming f ...

Ways to broaden React categories for embracing html attributes as props?

When designing a component that accepts both custom props and HTML attribute props, what is the best approach for creating the interface? The ideal interface should also accommodate React-specific HTML props, such as using className instead of class. Here ...

Implementing pagination for an Angular Material table using an HTTP request to set the page

How can I update the table page index when users click on next and previous buttons in an API that fetches data based on a specified Page number? It's important to note that I have already created a shared table. @Input() columns: Column[] = []; @In ...

NextJS Typescript Layout is throwing errors due to the absence of required props

After following the instructions on https://nextjs.org/docs/basic-features/layouts#with-typescript and making changes to my Home page as well as _app.tsx, I encountered an issue with the layout file Layout.tsx. The provided guide did not include an exampl ...

Sharing an array of React objects with PHP using REACT JS

I am new to React JS and I have a question regarding sending files as a react object array to php $_FILES using axios. Any help is appreciated, thank you in advance. Here is my react code: This is the code snippet: <Row> <Col lg={4}> ...

Utilize ngx-translate in Ionic 2 for translating menu items

I have successfully implemented ngx-translate for multi-language support in my application. However, I am now looking to extend this functionality to my menu items. How can I achieve this for my 3 menu items with different titles? ts file appPages: Pag ...

What is the best way to incorporate a @types module into a TypeScript file that is not already a module?

Setting the Stage: In the process of shifting a hefty ~3,000 line inline <script> from a web-page to a TypeScript file (PageScripts.ts) to be utilized by the page through <script src="PageScripts.js" defer></script>. This script entails ...

What are the steps to create a circular progress bar in an Ionic 3 application?

Can anyone help me create a circular progress bar in Ionic 3? I'm new to Ionic and have already attempted to install the jQuery circle progress package by running npm install jquery-circle-progress. The installation was successful, but now I'm un ...

Client-side condition handling in Angular 2

How can I change the icon image on a block/unblock button based on the user's active status? For example, showing an unlock image when the user is active and vice versa. Image https://i.stack.imgur.com/aM0ff.png Html <link href="../../font-aw ...