Customized object property names for an array of generic object types

I am working with an object in Typescript that has a data property structured like this:

type MyThing = {
  data: {
    options: {
      myKey: string,
      myValue: string
    }[],
    key: 'myKey',
    value: 'myValue'
  }
}

I want to create types of this structure using generics, but I am struggling to figure out the best approach. Here are the requirements:

  1. The base keys key and value must be provided, but additional keys like description could also be included.
  2. The options should always be an array of objects containing only the values of the keys specified (e.g., key, value, and potentially description).

While I can type this structure directly as shown above, I am unsure how to customize it with different keys or include extra options like descriptions.

An ideal solution would allow me to do something like this:

type MyThing = {
  data: DataComposer<['key', 'value']>
  // data: DataComposer<['key', 'value', 'description', ...]>
}

Answer №1

If you are looking for a type structure similar to this:

type DataComposer<
    K extends string,
    V extends string,
    OtherKeys extends Record<string, string> = Record<never, string>
> = {
    data: {
        options: { [optionKey in K | V | OtherKeys[keyof OtherKeys]]: string}[],
        key: K,
        value: V,
    } & { [OtherKey in keyof OtherKeys]: OtherKeys[OtherKey] }
}

In this context, K represents the string literal for the key while V corresponds to the value. Additionally, it allows for a third parameter for defining other custom properties.

You can implement it as follows:


type MyThing = DataComposer<'myKey', 'myValue'>
/*
type MyThing = {
    data: {
        options: {
            myKey: string;
            myValue: string;
        }[];
        key: "myKey";
        value: "myValue";
    };
}
*/

type MyThingWithOther = DataComposer<'myKey', 'myValue', { foo: 'myFoo' }>
/*
type MyThingWithOther = {
    data: {
        options: {
            myKey: string;
            myValue: string;
            myFoo: string;
        }[];
        key: "myKey";
        value: "myValue";
        foo: 'myFoo';
    };
}
*/

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

When using videojs, I have the ability to include a Text Track event handler, however, there is currently no option to remove it

I implemented a listener for the 'cuechange' event on a Text Track and it's functioning correctly. However, I am unable to figure out how to remove this listener. I have attempted the instructions below to remove the listener, but it continu ...

"Users have reported that the file upload preview feature in Angular 6 only works after the

I am currently utilizing Angular 6. In my application, I have a simple input type="file" field that passes data to an image source which displays the image I intend to upload. The issue I am facing is that when I select an image for the first time, nothi ...

Finding parameters in Angular 4

I am working on implementing a multilanguage feature in an Angular app and I need to establish the default language when the site loads. The two languages supported are Spanish and English, with Spanish being the default language. In order to achieve this, ...

What causes an interface to lose its characteristics when a property is defined using index signatures?

Here's the code snippet I'm having trouble with, which involves tRPC and Zod. import { initTRPC, inferRouterOutputs } from '@trpc/server'; import { z } from "zod"; const t = initTRPC.create(); const { router, procedure } = t; ...

The debate between using "this" versus "classname" to access static elements in

When working with TypeScript, I've observed that there are multiple valid approaches for accessing a static class member. class MyClass { private static readonly FOO: string = "foo"; public DoSomething(): void { console.log(MyClass.FOO);} pu ...

What could be causing the HTTP PUT requests to stop functioning properly after a number of requests?

Currently, I am developing an app for the premier league that allows users to create their own teams, input scores for matches, and view updated team statistics in a sortable table based on the Premier League rules. Issue: I have encountered a problem wi ...

Tips for preventing a wrapped union type from collapsing

It seems like there is an issue with Typescript collapsing a wrapped union type when it knows the initial value, which is not what I want. I'm uncertain if this is a bug or intended behavior, so I'm curious if there's a way to work around it ...

Setting up a project in TypeScript with Angular 2(+) and a Node/Express server is essential for successful

Searching for the optimal approach for a project similar to this: An Angular 2 (4) client coded in TypeScript A Node/Express backend also written in TypeScript Utilizing some shared (TypeScript) models accessible to both client and server code. Is it pr ...

The Typescript Select is displaying an incorrect value

Here's the code snippet I've been working with: <select #C (change)="changeSelect(zone.id, C.value)"> <option *ngFor="let town of townsLocal" [attr.value]="town.data" [attr.selected]="town.data === zone.town && 'selected& ...

Swap out a specific object within an observable array by comparing object properties

Currently, I am retrieving an observable array of custom IPix objects (Observable<IPix[]>) from a database using an API. After that, I update a record in the database by sending an edited version of the IPix object back to the API through a PUT reque ...

Ways to verify whether a checkbox is selected and store the status in the LocalStorage

Hey there, I'm still new to the world of programming and currently just a junior developer. I have a list of checkboxes and I want to save any unchecked checkbox to my local storage when it's unselected. Below is a snippet of my code but I feel l ...

typescript - instantiate an object using values stored in an array

Assume we have a model defined as follows. export interface Basicdata { materialnumber: number; type: string; materialclass: string; } We also have an array containing values that correspond directly to the Basicdata model in order, like this: ...

The html-duration-picker is not being displayed in the proper format

I've been working on integrating an external library that allows for inputting document length. Specifically, I'm using the html-duration-picker library, but it seems like the input functionality is not quite right for durations. Could it be th ...

Typescript service wrapper class returning Axios HEAD request

I am attempting to retrieve the header response using a custom Axios HTTP service wrapper. axiosClass.ts import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios"; class Http { private instance: AxiosInstance | null = n ...

The types for Cypress are not being detected by my Angular tsconfig file

I'm facing an issue with my Angular tsconfig not detecting the Cypress 12.3 types. I have tried numerous solutions to resolve this problem, but nothing seems to work, except for the extreme measure of starting the project over, which I think might sol ...

Enhance Material UI with custom properties

Is it possible to add custom props to a Material UI component? I am looking to include additional props beyond what is provided by the API for a specific component. For example, when using Link: https://material-ui.com/api/link/ According to the document ...

Displaying data from an Angular subscription in a user interface form

I am attempting to transfer these item details to a form, but I keep encountering undefined values for this.itemDetails.item1Qty, etc. My goal is to display them in the Form UI. this.wareHouseGroup = this.formBuilder.group({ id: this.formBuilder.contr ...

Tips for utilizing the patchValue method within a dynamic FormArray in Angular

When working with the first case (check out the DEMO link), patchValue() function can easily manipulate the select drop-down menu in a reactive FormGroup(), where only FormControl() is used. However, in the second case, I need to achieve the same functiona ...

Utilize Material-UI in Reactjs to showcase tree data in a table format

I am currently tackling a small project which involves utilizing a tree structure Table, the image below provides a visual representation of it! click here for image description The table displayed in the picture is from my previous project where I made ...

How to eliminate the ng-component tag from an Angular 8 table row template

I currently have a dynamic table component with 2 modes: Normal table - functioning properly Custom Row Template - encountering issues due to Angular adding the <ng-component> tag The logic within the TableComponent is not the main concern, it&apo ...