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

Having trouble retrieving information from Node.js service in AngularJS 2

I am currently expanding my knowledge of Angular and attempting to retrieve data from a node js service using Angular 2 services. When I access the node js services directly from the browser, I can see the results. However, when I attempt to fetch the dat ...

Angular version 7.2.1 encounters an ES6 class ReferenceError when attempting to access 'X' before it has been initialized

I have encountered an issue with my TypeScript class: export class Vehicule extends TrackableEntity { vehiculeId: number; constructor() { super(); return super.proxify(this); } } The target for my TypeScript in tsconfig.json is set to es6: ...

How to Position Logo in the Center of MUI AppBar in React

I've been struggling to center align the logo in the AppBar. I can't seem to get the logo to be centered both vertically and horizontally on its own. Here is my code from AppBar.tsx: import * as React from 'react'; import { styled, useT ...

Restricting the data type of a parameter in a TypeScript function based on another parameter's value

interface INavigation { children: string[]; initial: string; } function navigation({ children, initial }: INavigation) { return null } I'm currently working on a function similar to the one above. My goal is to find a way to restrict the initi ...

A static method written in Typescript within an abstract class for generating a new instance of the class itself

Imagine I have abstract class Foo { } class Bar1 extends Foo { constructor(someVar) { ... } } class Bar2 extends Foo { constructor(someVar) { ... } } I want to create a static method that generates an instance of the final class (all construct ...

Idea fails to detect imports

I have been attempting to use Angular2 in IntelliJ IDEA IDE. Although my code is valid (I have tried compiling and executing it), the IDE keeps showing me this error: https://i.stack.imgur.com/w6wIj.jpg Is there a way to configure IntelliJ IDEA to hide t ...

Utilizing Angular 14 and Typescript to fetch JSON data through the URL property in an HTML

Is there a way to specify a local path to a JSON file in HTML, similar to how the src attribute works for an HTML img tag? Imagine something like this: <my-component data-source="localPath"> Here, localPath would point to a local JSON fil ...

Issue with migrating TypeOrm due to raw SQL statement

Is it possible to use a regular INSERT INTO statement with TypeOrm? I've tried various ways of formatting the string and quotes, but I'm running out of patience. await queryRunner.query('INSERT INTO "table"(column1,column2) VALUES ...

I am completely baffled by the meaning of this Typescript error

In my code, there is a button component setup like this: export interface ButtonProps { kind?: 'normal' | 'flat' | 'primary'; negative?: boolean; size?: 'small' | 'big'; spinner?: boolean; ...

What is the best way to retrieve all designs from CouchDB?

I have been working on my application using a combination of CouchDB and Angular technologies. To retrieve all documents, I have implemented the following function: getCommsHistory() { let defer = this.$q.defer(); this.localCommsHistoryDB ...

The stacked bar chart in Apex is not displaying correctly on the x-axis

Currently, I am utilizing the Apex stacked bar chart within my Angular 16 project. In this scenario, there are 4 categories on the x-axis, but unfortunately, the bars are not aligning correctly with the x-axis labels. The data retrieved from my API is as ...

Updating part of an object using TypeScript

I am looking to create a utility function that takes an instance and an object as input, and then updates the instance with the values from the provided object fields. Below is the code for the utility function: function updateEntity<T, K extends keyof ...

Expanding the properties of an object dynamically and 'directly' by utilizing `this` in JavaScript/TypeScript

Is it possible to directly add properties from an object "directly" to this of a class in JavaScript/TypeScript, bypassing the need to loop through the object properties and create them manually? I have attempted something like this but it doesn't se ...

There are critical vulnerabilities in preact-cli, and trying to run npm audit fix leads to a never-ending loop between versions 3.0.5 and 2.2.1

Currently in the process of setting up a preact project using preact-cli: npx --version # 7.4.0 npx preact-cli create typescript frontend Upon completion, the following information is provided: ... added 1947 packages, and audited 1948 packages in 31s 12 ...

Configuring Typescript target and library to utilize Promise.allSettled on outdated web browsers

I am currently using TypeScript version 4.3.5 and Node.js version 14.18.1 in my project. The code I am working on is compiled to target both old and new browsers by setting target=es5 in the tsconfig file. I make use of both Promise.all and Promise.allSett ...

Required Ionic form field alert

Currently, I am developing a new app using ionic 3 and I am facing an issue with making inputs mandatory in my ionic-alert controller. Despite going through the ionic-component documentation and api documentation, I couldn't find a solution on how to ...

Exploring the depths of nested JSON with Angular2

I'm a beginner in Angular 2 using Typescript. I am trying to figure out how to access the 'D' and 'G' elements in my JSON data using NgFor. Is there a specific way or method that I can use to achieve this? [ { "A":"B", "C" ...

Error message: The property 'data' is not recognized within this context. Additionally, the property 'datatime' does not exist on the current type

I'm currently working on generating a graph using Firestore data and ng2charts. However, when I run my code, I encounter the following errors: Property 'data' does not exist on type 'unknown', causing an error in item.data Simila ...

Having trouble utilizing the DatePicker component in my react native application

I've encountered an issue while using DatePicker in react native. Whenever I try to use it, an error pops up saying: "render error a date or time must be specified as value prop". Here is the link to my repository: my github repository const [date, se ...

Compilation of Zod record with predefined keys

I need to create a dictionary similar to a zod schema for an object with multiple keys that are already defined elsewhere, all sharing the same value type. Additionally, all keys must be required. const KeysSchema = z.enum(['a', 'b', &a ...