Is it possible to create a class or interface based on a literal type?

Can you show me how to create a dynamic interface like this:

const fn = (v: string) => console.log(v)
class Methods {
  a: fn
  b: fn
}  

using literal type definitions for keys?

type Keys = 'a' | 'b'
const KeysList = ['a', 'b']

Maybe something along the lines of:

const fn = (v: string) => console.log(v)
class Methods {
  [key in Keys] = fn
}    
new Methods().a("example")

The idea is to minimize code repetition by providing a more concise way to define multiple keys with the same functionality.

Answer №1

One approach is to define a function that generates a constructor returning

Record<Keys,  (v: string) => void>
. This function can be utilized within the extends clause of a new class.

const KeysList = ['a', 'b'] as const
type Keys = typeof KeysList[number]


function extendWithKeys<K extends string, V>(keys: readonly K[], value: V): new () => Record<K, V> {
  return class {
    constructor() {
      for (let key of keys) {
        (this as any)[key] = value;
      }
    }
  } as new () => Record<K, V> 
}

const fn = (v: string) => console.log(v)
class Methods extends extendWithKeys(KeysList, fn) {

}    
new Methods().a("something")

Playground Link

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

TypeScript code to transform an array of strings into a custom object

I have a specific requirement that I have partially achieved using Java, but now I need to transition it to TypeScript on the client side. Please note: The input provided below is for illustrative purposes and may vary dynamically. Input: var input = [" ...

What could be the reason for Angular Router to receive query parameters twice?

I have an application that consists of two pages with lists. On Page A, clicking on an item will display the corresponding detail page. The detail page contains a list of sub-items, and clicking on any sub-item navigates to Page B with the sub-item's ...

Presenting information using mat-table in Angular 2

Everything seems to be working fine with the code as I am able to display the data in mat-cards successfully. However, when I try to display it in mat-tables, I encounter index errors. I have made sure to import matTableDataSource, DataSource, CdkTableModu ...

Is it possible to utilize multiple useMutation hooks within a single component?

I'm curious about how to utilize multiple mutations in a component effectively. For instance, if I need to both create and update the same component, how can I achieve this? Here's an example: const [createUser, {data}] = useMutation(CREATE_US ...

How should I proceed if a TypeScript definition file that I am relying on is lacking a specific definition?

I have encountered an issue while using the React type definitions for my project. The focus method is missing on elements in the array returned by the refs property, which prevents me from getting a specific example to work. The compiler error states: pro ...

How can I change a ReactNode into a text format?

I am looking for a way to convert the following code snippet into a string while preserving Tailwind CSS and other elements. My project uses Next.js with TypeScript and Tailwind CSS. Input : export default function Header_1() { return ( <div clas ...

Guide to making a GeoJSON Feature object with Typescript and react-leaflet

Attempting to generate a react element from a Feature in Typescript has been unsuccessful for me. (I'm utilizing react-leaflet + Typescript) With regular javascript, the process is as follows: <Map {...} <GeoJSON data={...} < ...

Having some issues with validating numbers in typescript

When implementing react hook form in my React app, I encountered an issue while validating specific fields and had to add some conditions to the schema. yup .object({ test1: yup.number().when('test2', (test2: number, schema: yup.NumberSchem ...

Ways to access nested keys in a TypeScript object as well as an array containing objects

As I develop a form generator, my goal is to achieve type safety for a nested object and an array of objects. Specifically, I want the 'name' property to correspond to the key of the respective object it belongs to. For instance, in the scenario ...

Disable dates that are more than 7 days from the current date using Material UI's Date

How can I restrict users from selecting dates more than 7 days after their initial selection? In the example image provided, the date of January 30th should be disabled for selection. https://i.stack.imgur.com/iTem4.png Below is the code snippet: const ...

Suggesting prop names for styled-components using TypeScript

Can anyone help me with styled-components to show suggestion props name? I've created a styled component called CardHeader and added props. interface ICardHeader { darkMode?:boolean } https://i.sstatic.net/eDlOv.png https://i.sstatic.net/urxvK.png ...

A guide on assigning a value to an array within a formgroup

if (Object.prototype.hasOwnProperty.call(data, 'checklists')) { if (Array.isArray(data.checklists)) { data.checklists.map((dt: any) => { dt.tasks.forEach((task: any) => { const dataArray = new FormGroup({ ...

Typescript fails to identify the parameter type of callbacks

I am facing a challenge with the function below and its callback type: type Callbacks = { onSuccess: (a: string) => void; }; function myFunction(event: string, ...args: [...any, Callbacks]) { } The function works correctly except for one issue - ...

What is the best way to launch an event when a component is accessed through navigation?

I am working on an angular2 application (RC5) that includes a chapter component containing a large template file named chapter.html. The template features different sections for each chapter specified by conditionals like: <div *ngIf="chapter == 1"> ...

Hidden input fields do not get populated by Angular submit prior to submission

I am in the process of implementing a login feature in Angular that supports multiple providers. However, I have encountered an issue with submitting the form as the loginProvider value is not being sent to the server. Below is the structure of my form: &l ...

Is it possible to create a distinctive property value within an ngFor loop that operates autonomously across two child components?

I am working on a functionality where, upon clicking on a specific car brand, the name of the person and their favorite car will be displayed at the bottom. However, I'm facing an issue where the car brand is being repeated among all items in the ngFo ...

Leverage the power of InfiniteSWR in your project by integrating it seamlessly with

If you're looking for a comprehensive example of how to integrate useSWR hooks with axios and typescript, check out the official repository here. import useSWR, { SWRConfiguration, SWRResponse } from 'swr' import axios, { AxiosRequestConfig, ...

Button with circular icon in Ionic 4 placed outside of the toolbar or ion-buttons

Is it possible to create a circular, clear icon-only button without using ion-buttons? I am trying to achieve the same style as an icon-only button within ion-buttons (clear and circular). Here is my current code: <ion-button icon-only shape="round" co ...

Struggling with creating a generic TypeScript structure?

My goal is to manipulate data structured like this: const exampleState = { elements : { element1: { values: { value1: 10, value2: 10, }, elementDetails : { detail1 : { values: { value1: ...

The Material UI button shifts to a different row

I need help adjusting the spacing between text and a button on my webpage. Currently, they are too close to each other with no space in between. How can I add some space without causing the button to move to the next line? const useStyles = makeStyles((the ...