"Exploring the world of Typescript declarations and the CommonJS module

I'm encountering confusion while creating declaration files (d.ts).

For instance, I have developed an NPM package called "a" with a single CommonJS module index.ts:

export interface IPoint {
    x: number;
    y: number;
}

export default function sub(one: IPoint, two: IPoint): IPoint {
    return {
        x: one.x - two.x,
        y: one.y - two.y
    };    
}

After compiling it, the generated a.d.ts looks like this:

export interface IPoint {
    x: number;
    y: number;
}
export default function sub(one: IPoint, two: IPoint): IPoint;

It seems that the compiler struggles to create valid d.ts for CommonJS. One must resort to utilities like dts-generator or manually wrapping:

declare module "a" 
{
    export interface IPoint {
        x: number;
        y: number;
    }
    export default function sub(one: IPoint, two: IPoint): IPoint;
}

Now, let's move on to developing package "b" which has a dependency on "a":

/// <reference path="node_modules/a/a.d.ts" />

import sub from "a"
import { IPoint } from "a"
export { IPoint }

export default function distance(one: IPoint, two: IPoint): number {
    var s = sub(one, two);
    return Math.sqrt(s.x * s.x + s.y * s.y);
}

So far, everything seems to be functioning correctly. Next, I aim to create a package "c" that depends on "b" (and so forth).

  1. How should I specify dependencies in the "b" module (link to "a.d.ts")? Should I try to specify them within "node_modules"? Or should I copy "a.d.ts" to the "/typings/" directory within the "b" package? And then copy "a.d.ts" and "b.d.ts" to "/typings/" in the "c" package (and beyond)?

  2. What is the significance of the "typings" section in "package.json"? In "b/package.json", I have written:

    "typings": "./b.d.ts"

This results in an error when compiling "c":

Exported external package typings file 'node_modules/b/b.d.ts' is not a module.
  1. How can I efficiently create d.ts files for CommonJS modules without having to manually write "declare module", "reference" statements, etc.?

Answer №1

It seems the compiler is unable to create valid d.ts files for CommonJS. One must use tools like dts-generator or manually wrap them:

However, this information is outdated (since version 1.6).

You can now simply compile module a by passing the declaration flag to tsc. The transpiler will automatically generate the declaration files for you.

Although these files are not external definition files, they serve as internal definitions.

Moreover,

Module b can easily locate and utilize these files if, in the package.json of module a, the typings entry points to the generated index.d.ts file

In summary:

For Module a:

  • compile with the declaration flag
  • update the typings entry to refer to the generated .d.ts file

For Module b:

  • simply import * as moduleA from 'a' or import {IPoint} from module 'a'

No need for cumbersome ///<reference= or manual typings anymore

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

ngClass causing styling issue when applying styles

When I use class names like error and info, the CSS works fine. For example, in this Angular app (latest version) here: https://stackblitz.com/edit/github-i4uqtt-zrz3jb. However, when I try to rename the CSS classes and add more styles, like in the examp ...

typeorm migration:generate - Oops! Could not access the file

When attempting to create a Type ORM migration file using the typeorm migration:generate InitialSetup -d ormconfig.ts command, I encountered an error: Error: Unable to open file: "C:\_work\template-db\ormconfig.ts". Cannot use impo ...

Creating a personalized 404 page in your Angular Project and configuring a route for it

I am currently working on an Angular project that includes a component named 'wrongRouteComponent' for a custom 404 page. Whenever a user enters a non pre-defined route, the 'wrong-route.component.html' should be displayed. However, I a ...

Tips for determining the datatype of a callback parameter based on the specified event name

Let's say we have the following code snippet: type eventType = "ready" | "buzz"; type eventTypeReadyInput = {appIsReady: string}; interface mysdk { on:(event: eventType, cb: (input: eventTypeCallbackInput) => void) => void } mysdk.on("ready", ...

Effortlessly glide through entire pages using the mouse wheel for seamless scrolling

I provide a seamless full-page scrolling experience using the mouse wheel. However, the scrollIntoView function does not seem to function within the @HostListener('wheel', ['$event']). Here is a snippet from app.component.html file: & ...

Creating a map in Typescript initialized with a JSON object

In my Typescript class, there is a map that I'm trying to initialize: public map:Map<string,string>; constructor() { let jsonString = { "peureo" : "dsdlsdksd" }; this.map = jsonString; } The issue I'm encounte ...

Transmit information from an IONIC 3 application to a PHP server using the POST method

Having trouble sending data from Ionic 3 to php via the http library using post? When php tries to retrieve it, it's unable to locate. Below is the Typescript file that generates the token to be sent to php and calls the php file on localhost (xampp) ...

Passing an array of items as a property to a child component in React with Typescript is not possible

In my project, I have multiple classes designed with create-react-app. I am trying to send an array of objects to child components as illustrated below. Items.tsx import * as React from 'react'; import ItemTable from './ItemTable'; imp ...

Merge two input fields into one to send data to the backend

I have created two input fields, one for selecting a date and the other for entering a time. Before submitting the form to the backend, I need to combine these two inputs into one variable. For example, <input type="text" name="myDate"> and <input ...

Resolving type error issues related to using refs in a React hook

I have implemented a custom hook called useFadeIn import { useRef, useEffect } from 'react'; export const useFadeIn = (delay = 0) => { const elementRef = useRef<HTMLElement>(null); useEffect(() => { if (!elementRef.current) ...

Workspace watch mode does not update Typescript definitions

Greetings to all who are reading this, I have created a React micro-frontend project using SPA v5.9, Webpack v5.75, Babel-loader v9.1, Ts-loader v9.4, and Yarn workspace v3.5. The project structure is very basic: Root SPA => Package Root Application S ...

Customizing MUI DataGrid: Implementing unique event listeners like `rowDragStart` or `rowDragOver`

Looking to enhance MUI DataGrid's functionality by adding custom event listeners like rowDragStart or rowDragOver? Unfortunately, DataGrid doesn't have predefined props for these specific events. To learn more, check out the official documentati ...

The NextJS image URL remains constant across various endpoints

Currently experiencing an issue with my Channel Tab where the icon and name of the channel are displayed. The problem is that every time I switch channels, the icon remains the same as the first channel I clicked on. PREVIEW This is the code I am current ...

Customizable column layout in react-grid-layout

I am looking to implement a drag and drop feature in which users can place items into a grid without fixed columns. The goal is that if an item is dragged from outside the grid boundaries and dropped to the right (an empty area), the grid will automaticall ...

Retrieve the implementation of an interface method directly from the constructor of the class that implements it

I am looking to create a function that takes a string and another function as arguments and returns a string: interface Foo { ConditionalColor(color: string, condition: (arg: any) => boolean): string; } I attempted to pass the ConditionalColor metho ...

What is the best way to trigger a Redux Toolkit action within a React Router DOM action?

My router setup looks like this: const router = createBrowserRouter([ { path: "/", element: <MainLayout />, errorElement: <Error />, children: [ { path: "/inventory", element: <Inve ...

Resolving the non-null assertion error in TypeScript and React: A step-by-step guide

My code snippet is as follows: type ItemProps = { status?: string; } <Items status={status!} /> // encountering an error with a warning about forbidden non-null assertion // @typescript-eslint/no-non- ...

Error: Attempting to modify the ip property of an #<IncomingMessage> object that is read-only

Currently, I am in the process of developing a middleware that is intended to assign the user's IP address based on the cloudflare header provided. This method has worked successfully on previous projects of mine, but now it seems to be encountering i ...

Creating a unique Elastic IP address for a single EC2 instance with the AWS CDK

I'm having an issue with my AWS CDK Stack where multiple Elastic IPs are being created for each public subnet in my VPC instead of just one. I only want one Elastic IP to be associated with a single EC2 instance. My simplified code snippet is as foll ...

Tips for preventing duplicate Java Script code within if statements

In my function, there are various statements to check the visibility of fields: isFieldVisible(node: any, field: DocumentField): boolean { if (field.tag === 'ADDR_KOMU') { let field = this.dfs_look(node.children, 'ADDR_A ...