Adjust the property to be optional or required depending on the condition using a generic type

    const controlConfig = >T extends 'input' | 'button'(config: Config<T>): Config<T> => config;

    interface Config<TYPE extends 'input' | 'button'> {
        type: TYPE;
        label: string;
        popover?: string;
        inputPlaceholder: TYPE extends 'input' ? string : never;
        key: string;
    }
    const config: Config<'input' | 'button'>[][] = [
        [
            controlConfig({
                type: 'button',
                label: 'user',
                popover: 'ID',
                key: 'user',
            }),
        ],
    ];

TS2345: Argument of type '{ type: "button"; label: string; popover: string; key: string; }' is not assignable to parameter of type 'Config<"button">'.   Property 'inputPlaceholder' is missing in type '{ type: "button"; label: string; popover: string; key: string; }' but required in type 'Config<"button">'

If there is no easy solution or preference for using a type alias, why doesn't TypeScript have something like making properties optional based on conditions?

Answer №1

When considering the type 'input' | 'button', it does indeed extend the type 'input'. This means that all objects in Config<'input' | 'button'>[][] will have a type property of 'input' | 'button' and must also include an inputPlaceholder property of type string.

Instead, what you might prefer is a union of objects differentiated by their type using Config<'input'> | Config<'button'>[][].

It's worth mentioning that using a generic may not be necessary; defining individual types and their union explicitly could be a better approach.

interface BaseConfig {
    // type: 'input' | 'button'; - can be defined but is not necessary
    label: string;
    key: string;
    popover?: string;
}
interface InputConfig extends BaseConfig {
    type: 'input';
    inputPlaceholder: string;
}
interface ButtonConfig extends BaseConfig {
    type: 'button';
}
type Config = InputConfig | ButtonConfig;

Subsequently, utilize Config[][].

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

How do I customize the appearance of console.log messages stored in a string variable?

Looking to enhance the appearance of my console log output in a JavaScript script by utilizing different styling options. Here's a sample scenario: s=`Title 1 \n This is some text that follows the first title`; s=`${s} \n Title 2 \n T ...

Is it possible to use AngularJS promise scheduling with `async`/`await` syntax?

When working with AngularJS services, TypeScript often recommends that I switch my code to use async/await functions. While I understand that using the await keyword is compatible with third-party promises because it essentially translates to calling then ...

Access another page by clicking on a link within an HTML document

Is it possible to include an anchor tag in demo1.html that, when clicked, will take the user to the demo2.html page and automatically select a data filter on that page? Here is the code snippet for demo1.html: <li> <div><a href="urunli ...

"Utilize Tuple in TypeScript to achieve high performance programming

I've been delving into TypeScript, focusing on the tuple type. As per information from the documentation, here is the definition of a tuple: A tuple type is another form of Array type that precisely knows its element count and types at specific posi ...

Achieving enlightenment with Satori in NextJS: Transforming SVG to PNG in a NodeJS Environment

I am currently exploring the capabilities of satori and integrating it into my next.js api routes. (I'm unable to utilize the vercel/og package). While I have successfully set everything up, I'm facing a challenge in converting the svg image gen ...

Creating two number-like types in TypeScript that are incompatible with each other can be achieved by defining two

I've been grappling with the challenge of establishing two number-like/integer types in TypeScript that are mutually incompatible. For instance, consider the following code snippet where height and weight are both represented as number-like types. Ho ...

I am unable to enter any text in an angular modal

Currently, I am facing an issue where I am unable to click on the search input field within a modal. The goal is to implement a search functionality in a table displayed inside a modal window. The idea is to have a list of hospitals where users can view d ...

Issue with RxDB: Collection not found upon reload

Exploring the integration of RxDB in my Angular project. I wanted to start with a simple example: export const LANG = { version: 0, title: "Language Key", type: "object", properties: { key: { type: "string", primary: true } }, requ ...

Having trouble persisting data with indexedDB

Hi there, I've encountered an issue with indexedDB. Whenever I attempt to store an array of links, the process fails without any visible errors or exceptions. I have two code snippets. The first one works perfectly: export const IndexedDB = { initDB ...

Create a duplicate of a div using JavaScript and modify the IDs of the inner elements within

I have two static div tags with a select tag and a text box inside, each with different IDs. When I clone the tag, it duplicates the same div tag in the DOM. How can I change the inner elements' tags? Below is the code snippet: <div id="m ...

Attempting to populate HTML content retrieved from my MySQL database

Currently, I am attempting to retrieve HTML content stored in my MySQL database using nodejs. The products are being retrieved from the database successfully. export async function getAllProducts() { try { const response = await fetch('ht ...

Example of fetching Pubnub history using AngularJS

I am not a paid PubNub user. I am utilizing the example code for an Angular JS basic chat application from PubNub, and I want to access the chat history. This specific example can be found on the PubNub website. git clone https://github.com/stephenlb/an ...

Upon reloading, Nextjs static build automatically redirects users to the homepage

After creating a static Next.js build using npm run export, I encountered an issue while deploying the build on S3 or any other web server such as Apache with .htaccess or Nginx. When accessing the routes by pasting them directly into the browser, they wou ...

The issue of footer overlapping the login form is observed on iOS devices while using Safari and Chrome

Unique ImageI am currently working on an Angular 8 project with Angular Material. I have successfully designed a fully functional login page. However, I am encountering a problem specifically on iOS devices such as iPhones and iPads, whether it is Safari o ...

What's the reason behind this file not opening?

When I try to insert this code into files index.html, style.css, and app.js, the page refuses to open. The browser constantly displays a message saying "The webpage was reloaded because a problem occurred." I am using a MacBook Air with macOS Big Sur and a ...

The custom validator in Material2 Datepicker successfully returns a date object instead of a string

Im currently working on developing a unique custom validator for the datepicker feature within a reactive form group. Within my code file, specifically the .ts file: form: FormGroup; constructor( private fb: FormBuilder, ...

Oops! The Route post function is missing some necessary callback functions, resulting in an undefined object error

I need to verify if a user has admin privileges. Every time I try calling the verifyAdminUser function from my router, I encounter the following error: Error: Route.post() requires callback functions but got a [object Undefined] at Route.(anonymous func ...

Receive the button click event outside of the canvas

Is there a way to have separate click events for the button and the ListItem? My focus is on the button click event only, without triggering the ListItem event. Live DEMO import React from "react"; import ReactDOM from "react-dom"; import ListItem from ...

retrieve information from a div using an AJAX request

I don't have much experience with ajax and javascript, but I need some assistance, so I will do my best to explain clearly! Below is the JavaScript associated with a button: $('#button-confirm').on('click', function() { $.ajax({ ...

Dragging the world map in D3 causes it to appear jumpy and erratic

I'm currently working on a Vue project to create an interactive world map that allows users to drag and zoom. I've attempted to integrate D3 for this purpose, but encountered an issue where the map jumps to the bottom right of the page whenever I ...