Tips for dynamically expanding a generic interface depending on the keys of its parent object

Consider the following definitions:

interface A {
    id?: string;
    name?: string;
}

interface BaseLabel<B extends Parent, Parent extends A> {
    keyStr?: keyof B & string;
}

interface RequiredLabel<B extends Parent, Parent extends A> extends BaseLabel<B, A> {
    label: string;
}

interface OptionalLabel<B extends Parent, Parent extends A> extends BaseLabel<B, A> {
    label?: string;
}

type Final<B extends Parent, Parent extends A> = RequiredLabel<B, Parent> | OptionalLabel<B, Parent>

I am seeking to enhance the Final type so that Parent keys must have a required label (based on RequiredLabel) while all other B keys can have an optional label (based on OptionalLabel).

interface Parent extends A {
    value?: string;
}

interface Child extends Parent {
    isDate?: boolean;
}

const fields: Final[] = [
   {id: '1', name: '1', isDate: true},
   {id: '2', name: '2', isDate: true, label: 'label 2'},
   {id: '3', name: '3', value: '3', label: 'label 3'},
];

All entries related to the parent entity must include a mandatory label, while others are optional.

Could someone assist me in achieving this specificity?

Answer №1

After much trial and error, I finally found the solution that resolved my issue:

interface MustHaveLabel<B extends Parent, Parent extends A> {
    keyName: keyof Parent & string;
    labelText: string;
}

interface MaybeHaveLabel<B extends Parent, Parent extends A> {
    keyName: keyof Omit<B, keyof Parent> & string;
    labelText?: string;
}

type FinalResult<B extends Parent, Parent extends A> = MustHaveLabel<B, Parent> | MaybeHaveLabel<B, Parent>;

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

Expand the ApiGateProxyEvent category from aws-lambda

Looking to enhance the ApiGateProxyEvent of aws-lambda in d.ts. Initial attempts replaced the entire APIGatewayProxyEvent instead of extending it as intended. declare namespace AWSLambda { interface APIGatewayProxyEvent { body: any; user: any; ...

When the file is active on a local machine, the bot commands run smoothly. However, these commands do not execute on a remote

Lately, while working on coding a discord bot using discord.js, I came across an issue. Whenever I run my bot on my local machine, all the commands work perfectly fine. However, after committing and pushing the code to GitHub, and then allowing buddy.works ...

Expanding interfaces in TypeScript

Within an interface, I have a list of props that I would like to modify by extending the interface type in the following manner: Modification of Prop types Addition of new fields interface Request { Id: NullProp<number>, Name: NullProp< ...

Tips for creating a deepCss selector for an input Textbox in Protractor

When I attempt to use sendKeys in an input textbox with Protractor, the element is located within a shadow-root and there are three separate input textboxes. ...

Inheritance-based type inference

I have created a class hierarchy to manage inheritance in my code. Here is an example of how it looks: class A { clone(): A { return new A() } methodA() { return this.clone() } } class B extends A { clone(): B{ return new B() } ...

What is the process for specifying a method on a third-party class in TypeScript?

I'm facing a challenge while trying to extend a third-party class in TypeScript. The issue is that I am unable to access any existing methods of the class within my new method. One possible solution could be to redeclare the existing methods in a sep ...

Using a variety of objects in TypeScript arrays

How to effectively implement a superior class in TypeScript for an array containing diverse objects that inherit from the same class, without triggering errors? This is my attempt: interface IVehicle{ modelName: string } interface ICar extends IVehi ...

Error message: Cordova not found - unable to use 'ionic native' 3 for CRUD operations with SQLite database

I am attempting to manage CRUD data with SQLite in Ionic 3, but unfortunately cordova is not functioning as expected. https://i.sstatic.net/5m411.png ...

What is the reason behind taps in TypeScript only registering the first tap event?

One issue I am encountering is that only the first tap works when clicked, and subsequent taps result in an error message: Uncaught TypeError: Cannot read properties of undefined (reading 'classList') Here is the code I am using: https://codepen ...

Please provide either a string or an object containing the proper key for TypeScript

Within my project, the languageSchema variable can either be a string or an object containing the 'Etc' key. The corresponding interface is defined as follows: let getLanguageSchema = (language: string): string => languagesSchemas[language]; ...

Issue with pre-selected default value in AngularJS TypeScript Kendo UI DropDownList

I have successfully implemented a list of objects for items, but now I am facing a challenge in adding a default selected value. Below is the HTML code for the drop-down: <select kendo-drop-down-list k-options="selectItems" k-ng-mode ...

Creating reusable date logic with date-fns: A guide

In my Weather App, I successfully implemented code to display the date. However, I'm now contemplating the idea of writing reusable code. Is there a way for me to combine "const date and day" and use them separately? import { Weather } from "./ty ...

Converting data types of a destructured property

In my Next.js application, I'm using a router hook and destructuring like this: const { query: { run_id }, } = useRouter(); The type of `run_id` is as follows: run_id: string | string[] | undefined I tried to typecast it as shown below, but it doe ...

Tips for parsing data arrays in HTML templates

I have three variables and I created an array where I pushed all these three variables in. In my HTML template, I am using a table. I tried using *ngFor but it is not working, and also attempted string interpolation which also did not work. Currently, I ...

Encountering an error in Angular where the property does not exist in type

Struggling to create a collapsible menu within my header component in an Angular project, I've hit a snag with proper JSON formatting. The error message that keeps popping up reads: Error: src/app/components/header/header.component.html:48:49 - error ...

Error: The activation of the extension in vscode failed because the module cannot be found using non-relative import

Currently, I am in the process of developing a Visual Studio Code extension. In this project, I have opted to utilize non-relative imports in TypeScript. For instance: import ModuleA from 'modules/ModuleA'; The actual location of the folder for ...

Toggle the visibility of a modal in code across various components in an Angular 4 project using Typescript

As I was working on my university App, I encountered an issue while attempting to open a Bootstrap modal in code from a different component. Opening a component in code from the same component posed no problems for me as I use JQuery and it functions perfe ...

Error encountered in Typescript: SyntaxError due to an unexpected token 'export' appearing

In my React project, I encountered the need to share models (Typescript interfaces in this case) across 3 separate Typescript projects. To address this, I decided to utilize bit.env and imported all my models to https://bit.dev/model/index/~code, which wor ...

Obtaining a list of dates for a particular week using React DayPicker

I'm seeking the ability to click on a specific week number within the react DayPicker and receive an array of all dates within that week. The DayPicker package I am using can be found here: I've copied the example code from react DayPicker to e ...

Trouble with Excel Office Script setInterval functionality

Trying to automatically recalculate an Excel worksheet every second using Office Script. Unfortunately, my initial approach did not succeed. function sendUpdate(sheet: ExcelScript.Worksheet) { console.log('hi'); sheet.calculate(true); } func ...