When working with Typescript, you can declare an interface and split its definition across multiple files

I've been developing a software application that utilizes WebSocket with the NodeJS ws package. My networking structure revolves around a module responsible for handling message reception and transmission. Given that I'm working with TypeScript, I wanted to leverage its type checking capabilities, which can be quite useful at times. Consequently, I created two types:

// networking.ts
export class Message {
    constructor(
        public request: string,
        public params: Params) {}
}

export interface Params {
    messageId?: number;
}

While this setup functions smoothly when only the messageId parameter is needed, complications arise when I also need to include a nickname as a parameter. While I could simply add it to the existing Params definition, I prefer not to burden the networking engine with knowledge of all possible parameters that may need to be sent (considering there are multiple parameters in play)...

Is there a way to achieve something like the following:

// profile-params.ts
export interface Params {
    nickname:string;
}

// admin-params.ts
export interface Params {
    authorizations: string[];
}

Thus enabling the merging of the Params declaration? I explored the official documentation, but was unable to make it function across different files.

Thank you

Answer №1

@Daniel W Strimpel is alright, assuming your interface does not originate from a module and you are comfortable with placing it in the global scope.

If you prefer the interface to be included in a module, you can utilize module augmentation to expand the interface:

//pModule.ts
export interface Params {
    messageId: number;
}

//pAug.ts
import { Params } from "./pModule";
declare module './pModule' {
    interface Params {
        nickname: string;
    }
}
//usage.ts
import {Params} from './pModule'
import './pAug'

let p : Params = {
    nickname: '',
    messageId: 0
}

Answer №2

Utilize generics for enhanced type safety:

export class Message<T extends Parameters> {
  constructor(
    public request: string,
    public params: T
  ) { }
}

export interface Parameters {
  messageId?: number
}

// profile-params.ts
export interface ProfileParams extends Parameters {
  nickname: string
}

const message = new Message<ProfileParams>('', { nickname: 'a' })

Answer №3

At this moment, I don't have all the reasons clarified as to why (aside from the fact that exporting something turns it into a module), but the method I am aware of to achieve this is by segregating them into their own separate files where nothing gets exported and then importing these files (omitting the { Params } from syntax).

// ./message/params.model.ts
interface Params {
    messageId?: number;
}

// ./user/params.model.ts
interface Params {
    nickname: string;
}

// ./authorization/params.model.ts
interface Params {
    authorizations: string[];
}

// ./some.component.ts
import './message/params.model.ts';
import './user/params.model.ts';
import './authorization/params.model.ts';

const params: Params = {
    authorizations: ['black-belt', 'secret-service'],
    nickname: 'ninja',
    messageId: 1
};

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

Exploring the Augmented Theme in Material UI Using TypeScript and the "keyof" Operator

I've recently started working with TypeScript and I'm facing an issue that I can't seem to solve. Here's the problem: I extended my Material UI theme with the following types: declare module '@material-ui/core/styles/createPalette& ...

Using TypeScript to specify data types in the Vue data object

I am currently utilizing Vue.js with Typescript in a webpack project. Following the guidelines provided in the Recommended Configuration in my tsconfig.json, I have set: "strict": true, Within one of my components, I have: declare interface P ...

Having trouble reloading a seekbar (input range) in Angular 7 with a function?

I am currently in the process of developing a music player using Angular 7, and below is the HTML code for my component: <div class="track-controller"> <small>{{musicPlayerService.getCurrentTime()}}</small> <div class="progress- ...

Tips on saving a cookie using universal-cookie

I followed a solution on Stack Overflow to set a cookie in my React application. However, the cookie expires with the session. Is there a way I can make this cookie persist beyond the session so it remains even when the browser is closed and reopened? ex ...

Displaying related objects information from a single object in AngularFire2 can be achieved by following these steps

As a newcomer to Angular and Firebase, I apologize if my question seems basic. I'm seeking guidance on how to display related object information from one object in angularfire2. Specifically, I want to show the role names assigned to a user. Here is ...

Guide on extracting just the key and its value from a Filter expression in a DynamoDB Query using Typescript

Presented here is a filter expression and Key Condition. The specific set of conditions are as follows: {"Age":{"eq":3},"Sex":{"eq":"MALE"}} const params: QueryCommandInput = { TableName: my_tab ...

Oops! Issue: The mat-form-field is missing a MatFormFieldControl when referencing the API guide

I included the MatFormFieldModule in my code like so: import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; ...

What is the reason behind the lag caused by setTimeout() in my application, while RxJS timer().subscribe(...) does not have the same

I am currently working on a component that "lazy loads" some comments every 100ms. However, I noticed that when I use setTimeout for this task, the performance of my application suffers significantly. Here is a snippet from the component: <div *ngFor ...

Using the Async feature, I can retrieve the value of a string type when the return type of a function is Promise<any>

While working on a custom pipe, I encountered a situation that puzzled me. Can you explain why the code snippet below is considered valid? async transform(value: any): Promise<string> { let fullNameBasedOnPreference: string; fullNameBasedOnP ...

Unexpected TypeError when using Response.send()

Here is a snippet of my simple express code: const api = Router() api.post('/some-point', async (req, res, next) => { const someStuffToSend = await Promise.resolve("hello"); res.json({ someStuffToSend }); }) In my development environmen ...

Expectation in Observable: Unable to provide data retrieval

In my Angular 7 and Typescript project, I am faced with the challenge of reading a json file from within a zip file. Although I am able to successfully display the correct json output on the console, I am struggling to return this json data from the functi ...

Setting up a custom PrimeNG theme to match our unique style is a great way to

I am currently using the most recent version of "primeng": "^12.2.0", and I am looking to implement my own custom theme for primeng. Despite searching through numerous blogs, I have yet to find a solution. In an attempt to create my cu ...

The production build for Angular 9 Keyvalues pipe fails to compile

After successfully running my app on the development server with ng serve, I encountered a failure when trying to build it for production. The error message that popped up was: ERROR in src/app/leaderboard/leaderboard.component.html(9,17): Argument of typ ...

Snackbar and RTK Query update trigger the error message: "Warning: Cannot update during an existing state transition."

I've built a basic ToDos application that communicates with a NodeJS backend using RTK Query to fetch data, update state, and store cache. Everything is functioning properly as expected with the communication between the frontend and backend. Recently ...

Angular error: Trying to assign a value of type ArrayBuffer to a string type

Is there a way to display a preview of a selected image before uploading it to the server? Here is an example in HTML: <div id="drop_zone" (drop)="dropHandler($event)" (dragover)="onDragover($event)"> <p>drag one or more files to ...

Extending an External Object with Custom Properties in TypeScript

When working with an external library, I often find myself needing to add new properties to passed-in parameters. Instead of using (<any>conv.data) due to the compiler error Object is of type 'unknown', I'm curious if there's a mo ...

What are the best strategies to troubleshoot issues during NPM Install?

I keep encountering errors during the npm install process, but everything works fine when I use npm install --force in my local environment. However, the issues persist during the repository build as my .yaml file script contains "npm install". Can anyone ...

Implementation of a function in Typescript that can be defined with a

I am currently diving into the Typescript specification and I'm facing a challenge in creating a functional implementation for describable functions. https://www.typescriptlang.org/docs/handbook/2/functions.html The provided example lacks completene ...

What is the best way to initiate multiple processes in Node.js and ensure they finish before proceeding?

When working with Node.js and TypeScript, my goal is to initiate multiple processes using the spawn function. Afterwards, I aim to ensure all of these processes are completed before proceeding to execute any additional commands. ...

Surprising Outcome when Dealing with Instance Type - Allowing extra properties that are not explicitly stated in the type

I've come across an issue with the InstanceType Utility Type. I am trying to create a function that takes a class constructor and an instance of that class. For instance: export type Class<T=any> = { new(...args: any[]): T; }; function acceptC ...