Using a generic name as a JSON key in a TypeScript file

I received data from an API call

const tradingApiResponse = {
  Timestamp: "2024-01-15T12:00:00",
  Ack: "Success",
  Version: 1,
  Build: "1.0.0",
  UserDeliveryPreferenceArray: {
    NotificationEnable: [
      { EventType: "ItemSold", EventEnable: "true" },
      { EventType: "ItemShipped", EventEnable: "false" }
    ],
  },
};

The attributes Timestamp, Ack, Version, and Build are standard in all responses, however the subsequent key UserDeliveryPreferenceArray can change based on the request. To represent this variability in interfaces/types, I have designed the following structure

export interface EbayTradingRoot {
  Timestamp: string;
  Ack: string;
  Version: number;
  Build: string;
}

export interface UserDeliveryPreferenceArray {
  NotificationEnable: NotificationEnable[];
}

export interface NotificationEnable {
  EventType: string;
  EventEnable: string;
}

In addition to these, I've created a specialized interface as follows

export interface UserDeliveryPreferenceArrayResponse extends EbayTradingRoot {
  UserDeliveryPreferenceArray: UserDeliveryPreferenceArray;
}

I am exploring alternative approaches like the one shown below for more flexibility

export interface EbayTradingRoot<T> {
  Timestamp: string;
  Ack: string;
  Version: number;
  Build: string;
  [T]: T;
}

Answer №1

Impressed by the generic approach showcased in your solution. You can leverage an intersection type when utilizing types over interfaces. This enables the creation of new types stemming from the generic EbayTradingRoot type.

type UserDeliveryPreferenceArray = {
  NotificationEnable: NotificationEnable[];
};

type NotificationEnable = {
  EventType: string;
  EventEnable: string;
};

type EbayTradingRoot<T extends Record<string, unknown>> = {
  Timestamp: string;
  Ack: string;
  Version: number;
  Build: string;
} & T;

type ExtendedEbayTradingRoot = EbayTradingRoot<{
  UserDeliveryPreferenceArray: UserDeliveryPreferenceArray;
}>;
// type ExtendedEbayTradingRoot = {
//     Timestamp: string;
//     Ack: string;
//     Version: number;
//     Build: string;
// } & {
//     UserDeliveryPreferenceArray: UserDeliveryPreferenceArray;
// }

TypeScript Playground

Answer №2

It's important to note that the interface name UserDeliveryPreferenceArray should not be used as a key.

To define the type, you can follow this structure:

export type UserDeliveryPreferenceArrayResponse = EbayTradingRoot & { UserDeliveryPreferenceArray: UserDeliveryPreferenceArray }

When creating an interface, use the following template:

interface UserDeliveryResponse {
  UserDeliveryPreferenceArray: UserDeliveryPreferenceArray
}

export interface IUserDeliveryPreferenceArrayResponse extends EbayTradingRoot, UserDeliveryResponse {}

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

Steps for inserting a script tag in an Angular component

My Angular/Typescript website needs to integrate a third-party script that generates a table. However, I'm facing issues with rendering the table within the home.component.html file. I've managed to embed the script, but it doesn't seem to ...

Troubleshooting Issue: Ionic 3 and Angular ngForm not transmitting data

Attempting to create a basic crud app with ionic 3, I am encountering an issue where new data cannot be inserted into the database. The problem seems to lie in the PHP server receiving an empty post array. Below is my Ionic/Angular code: Insert.html < ...

Passing a type as an argument in Typescript

How can I pass a type as a parameter in Typescript? type myType = {} const passingType = (t: Type) => { const x : t = {} } passingType(myType); I keep receiving TypeScript errors. 't' is referencing a value, but it is being used as a t ...

Unable to interact with Span in a table cell - Protractor/Typescript error

I am facing an issue where clicking on the Span Element within a Grid cell is not working. I have tried using actions and the code below, but neither worked for me. Any advice would be greatly appreciated. async SaveorCancelRow() { var table = this. ...

Utilizing *ngFor to display elements with odd indices

Within my Angular application, I have successfully used a loop to populate the 4 employeeList components. Here is the code snippet: <div *ngFor="let record of records"> <p-panel> <div comp-employeeList [listFilter]="record.Filte ...

Containerizing Next.js with TypeScript

Attempting to create a Docker Image of my Nextjs frontend (React) application for production, but encountering issues with TypeScript integration. Here is the Dockerfile: FROM node:14-alpine3.14 as deps RUN apk add --no-cache tini ENTRYPOINT ["/sbin ...

Tips for arranging datasets in React Chart.js 2 to create stacked bar charts

Currently, I am facing an issue with sorting the datasets displayed in each stacked bar chart in descending order as they are showing up randomly. Here is the snippet of my code: import React from 'react'; import { Chart as ChartJS, CategoryS ...

I am currently facing challenges retrieving data from a post request in my Angular/Typescript frontend application connected to an ASP.NET backend

I am currently working on a web application that relies on backend processing. To communicate between my Angular(v14)/Typescript front end and an ASP.NET backend, I am sending a post request. Backend Code [HttpPost] public async Task<string> Process ...

Defining TypeScript class events by extending EventEmitter

I have a class that extends EventEmitter and is capable of emitting the event hello. How can I properly declare the on method with a specific event name and listener signature? class MyClass extends events.EventEmitter { emitHello(name: string): void ...

What are some methods for retrieving RTK Query data beyond the confines of a component?

In my React Typescript app using RTK Query, I am working on implementing custom selectors. However, I need to fetch data from another endpoint to achieve this: store.dispatch(userApiSlice.endpoints.check.initiate(undefined)) const data = userApiSlice.endpo ...

Having trouble implementing the Material UI time picker because it does not meet the required DateTime format

REVISE I recently switched my dataType from DateTime to TimeSpan in my code. I have a functioning MVC version that already uses TimeSpan, and the times are posted in HH:MM format. Now, I am unsure if the issue lies with the headers set up on Axios or if it ...

Array of colors for Wordcloud in Angular Highcharts

I am currently utilizing Angular Highcharts 9.1.0 and facing an issue with generating a word cloud that incorporates specific colors. Despite including color values in the array, they do not seem to be applied as intended. Take a look at the code snippet b ...

Combine objects by selecting attributes from multiple objects

declare type A = {type: 'TypeA', attr1: string} declare type B = {type: 'TypeB', attr2: string} declare type U = A | B When I use type X = Pick<U, 'type'>, I get: { type: 'TypeA' | 'TypeB' } But I a ...

"Disabling a FormControl within a FormArray in Angular 4: A Step-by-

I've come up with a code snippet below that I thought would disable the FormControl in a FormArray. some.component.html <form [formGroup]="testForm"> <div *ngFor="let num of countArr"> <input type="text" formNameArray="arr ...

While attempting to utilize npm install, I encounter an error on a discord bot stating "msvsVersion is not defined."

Struggling with self-hosting a TypeScript discord bot, the setup process has been a puzzle. It's supposed to generate a build directory with an index.js file, but it's unclear. Installed Visual Studio Build Tools 2017 as required, yet running npm ...

Enhancing component and view functionality in Angular

Recently, I started working on Angular 11 and encountered a simple yet challenging question. Despite my best efforts, I have been unable to find a suitable answer. In an attempt to utilize Object-Oriented Programming (OOP) concepts within Angular, I create ...

Can optional parameters be used to restrict TypeScript overloads in any way?

My objective is as follows: interface ColorRgb { red: number; green: number; blue: number; } function rgbToHex(red: ColorRgb, green?: undefined, blue?: undefined): string function rgbToHex(red: number, green: number, blue: number): string function r ...

Encountering obstacles when trying to implement mongoose virtuals in a TypeScript environment

I have been exploring how to utilize virtuals in mongoose with typescript. Let's say I have an interface for defining a user. interface User { id: mongoose.ObjectId; name: string; likes: string; } Next, I define a schema for mongoose. // ...

Using TypeScript with React: Initializing State in the Constructor

Within my TypeScript React App, I have a long form that needs to dynamically hide/show or enable/disable elements based on the value of the status. export interface IState { Status: string; DisableBasicForm: boolean; DisableFeedbackCtrl: boolean; ...

A guide on implementing isomorphic types in TypeScript

Consider the following scenario with two files, file.ts: let a: Message = "foo" let b: Message = "bar" let c: Message = "baz" Now let's introduce a second file, file2.ts type Message = string function fun(abc: Message): void { } When using functi ...