Implementing typing for a module that exports an instance of a particular class

Attempting to create a .d.ts file for the foo-foo-mq module has presented some challenges.

Following the documentation, a 'foo-foo-mq' folder was created within the 'typings' directory at the project's root. An index.d.ts file was then added with the following content:

declare module 'foo-foo-mq' {

  function configure(options: TopologyOptions): { done: (callback: () => void) => void };

  export enum TopologyExchangeType { FANOUT = 'fanout', TOPIC = 'topic', DIRECT = 'direct' }

  export interface TopologyExchange {
    name: string;
    type: TopologyExchangeType;
    autoDelete?: boolean;
    publishTimeout?: number;
    alternate?: string;
    persistent?: boolean;
  }

  export interface TopologyQueue {
    name: string;
    autoDelete: boolean;
    subscribe: boolean;
    queueLimit?: number;
    limit?: number;
    deadLetter?: string;
  }

  export interface TopologyBinding {
    exchange: string;
    target: string;
    keys: Array<string>
  }

  export interface TopologyOptions {
    connection: {
      name?: string;
      user?: string;
      pass?: string;
      host?: string | string[];
      port?: number;
      timeout?: number;
      vhost?: string;
      replyQueue?: string;
    },
    exchanges?: TopologyExchange[];
    queues?: TopologyQueue[],
    bindings?: TopologyBinding[]
  }
}

The usage of the module seems to be working as expected:


import rabbit from 'foo-foo-mq'

rabbit.configure()

However, assigning the 'rabbit' variable to a private property poses a challenge in determining its type:

For example:


class SomeHiLevelClass {
   constructor(private rabbit:????) {}
}

Upon examining the source code of foo-foo-mq, it was discovered that it exports an instance of the Broker class:

class Broker { ... }
module.exports  = new Broker()

Is there a way to properly describe this in the .d.ts file?

Answer №1

After creating an actual ts file, transpiling it, and examining the .d.ts file for insights, I was able to figure out how to achieve this. Here is the solution:

declare module 'foo-foo-mq' {

  export enum TopologyExchangeType { FANOUT = 'fanout', TOPIC = 'topic', DIRECT = 'direct' }

  export interface TopologyExchange {
    name: string;
    type: TopologyExchangeType;
    autoDelete?: boolean;
    publishTimeout?: number;
    alternate?: string;
    persistent?: boolean;
  }

  export interface TopologyQueue {
    name: string;
    autoDelete: boolean;
    subscribe: boolean;
    queueLimit?: number;
    limit?: number;
    deadLetter?: string;
  }

  export interface TopologyBinding {
    exchange: string;
    target: string;
    keys: Array<string>
  }

  export interface TopologyOptions {
    connection: {
      name?: string;
      user?: string;
      pass?: string;
      host?: string | string[];
      port?: number;
      timeout?: number;
      vhost?: string;
      replyQueue?: string;
    },
    exchanges?: TopologyExchange[];
    queues?: TopologyQueue[],
    bindings?: TopologyBinding[]
  }

  export class Broker {
    configure(options: TopologyOptions): Promise<void>;
  }

  const _default: Broker

  export default _default;
}

With this implementation, I am now able to utilize the following code:

import rabbit, { Broker } from 'foo-foo-mq'
...
constructor(private rabbit: Broker ) {}
...
rabbit.configure() 

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

Using jest to simulate a private variable in your code

I am working on unit testing a function that looks like this: export class newClass { private service: ServiceToMock; constructor () { this.service = new ServiceToMock() } callToTest () { this.service.externalCall().then(()=& ...

Issues encountered when attempting to add a new user on Firebase

I am facing an issue with this function that is supposed to add new users to my firebase database, but for some reason, it's not working. exports.createUserWithEmailAndPassword = functions.https.onCall( async(data, context) => { const { ...

Using Typescript with Material UI Select

I have implemented a dropdown menu using Material UI select labeled "Search By." When the menu is clicked, it displays a list of options. I aim to store the selected option and update the label "Search By" with the chosen option. export default function U ...

What is the appropriate return type for this function in TypeScript?

Seeking clarity on a fundamental TypeScript concept here. I've noticed that Google Cloud examples use JavaScript, and I'm in the process of converting one to TypeScript. Source: https://cloud.google.com/storage/docs/listing-buckets#storage-list ...

Displaying the default value in a Material-UI v5 select component

I am looking to display the default value in case nothing has been selected yet for the mui v5 select component below, but currently it appears empty... <StyledCustomDataSelect variant='outlined' labelId='demo-simple- ...

Easy-to-use blog featuring Next.js 13 and app router - MDX or other options available

Currently in the process of transitioning a Gatsby website to Next.js (v13.4) and utilizing the new App Router. However, I'm facing some challenges when it comes to migrating the blog section over because there isn't much accurate guidance availa ...

Angular two - Communication between parent and children components using a shared service

I am currently working on establishing communication between child components, but according to the documentation, I need to utilize services for this purpose. However, I am facing challenges in accessing service information. When I try to assign the retur ...

Error: Unable to access _rawValidators property of null object

I'm currently facing an issue with formgroup and formcontrol in Angular. When I run ng serve, it's showing an error in the console. Does anyone have a solution for this? TypeError: Cannot read properties of null (reading '_rawValidators&a ...

Navigating through pages: How can I retrieve the current page value for implementing next and previous functions in Angular 7?

Greetings, I am a new learner of Angular and currently working on custom pagination. However, I am facing difficulty in finding the current page for implementing the next and previous functions. Can anyone guide me on how to obtain the current page value? ...

Exploring TypeScript interfaces with optional properties and returning types

As a newcomer to TypeScript, I am currently exploring the documentation and came across an example in the "Optional Properties" section that caught my attention: interface SquareConfig { color?: string; width?: number; } function createSquare(config: ...

"Creating a Typescript property that is calculated based on other existing properties

I am working on a Typescript project where I have a basic class that includes an `id` and `name` property. I would like to add a third property called `displayText` which combines the values of these two properties. In C#, I know how to achieve this using ...

Installation and execution of TypeScript jQuery / Bootstrap definition file on a local machine using npm typings: A step-by-step guide

Struggling to set up TypeScript jQuery and Bootstrap definition files in my new project using npm typings. Below are the steps I followed: 1- Open cmd, navigate to my project folder, and enter the following commands: npm install typings --global typings ...

Troubleshooting Angular HTTP: Issue with the HTTP request headers not updating

// assigning the httpclient protected _http: HttpClient = inject(HttpClient); // defining the options for the request const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/tcc' }), observe: 'resp ...

The property 'toLowerCase' cannot be accessed as it is undefined or null

Scenario: A textbox is present with a list of data below it. Upon typing in the textbox, the list gets filtered based on the text entered. Code: Pipe: @Pipe({ name: 'search' }) export class SearchPipe implements PipeTransform { transform( ...

Tips for adding a mat-error to a mat-input-field on-the-fly

To handle user input exceeding maxLength and dynamically add < mat-error > to the DOM in case of an error, I have implemented an attribute directive that enforces the character limit on input fields. This directive is used across multiple files in the proj ...

When embedding HTML inside an Angular 2 component, it does not render properly

Currently, I am utilizing a service to dynamically alter the content within my header based on the specific page being visited. However, I have encountered an issue where any HTML code placed within my component does not render in the browser as expected ( ...

Is tsconfig.json Utilized by Gatsby When Using Typescript?

Many blog posts and the example on Gatsby JS's website demonstrate the use of a tsconfig.json file alongside the gatsby-plugin-typescript for TypeScript support in Gatsby. However, it seems like the tsconfig.json file is not actually utilized for conf ...

error TS2304: The term 'MediaRecorder' is not recognized

How can I add audio recording capability to my Angular application using media recorder? Unfortunately, I am encountering the following error: Error TS2304: 'MediaRecorder' cannot be found If anyone knows a solution for this issue, your help w ...

A TypeScript interface or class

Just had a lively discussion with a coworker and wanted to get some clarification. When shaping an object in TS, should we use a class or an interface? If I need to ensure that a function returns an object of a specific type, which one is the best choice? ...

The term 'MapEditServiceConfig' is being incorrectly utilized as a value in this context, even though it is meant to refer to a type

Why am I receiving an error for MapEditServiceConfig, where it refers to a type? Also, what does MapEditServiceConfig {} represent as an interface, and what is the significance of these brackets? export interface MapEditServiceConfig extends AppCredenti ...