Utilizing TypeScript to invoke a method via an index signature

Here is a snippet of my code, where I am attempting to call a method using an indexed signature. It functions properly when the function name is manually added, but how can I call it using object notation for dynamic calls?

 createFormControl(formControls:PatientFormProps[]):void {
    for (const control  of formControls) {
      const newPatientFormControl = new FormControl();
      if (control.options.required) {
        const value = { label: 'email' };
        newPatientFormControl.setValidators([Validators.required, PatientFormService.formProps["email"]]);//works
        newPatientFormControl.setValidators([Validators.required, PatientFormService.formProps[value.label]);//error
      }
      this.patientForm.addControl(control.key, newPatientFormControl);
    }
    console.log(this.patientForm);
  }

Error Message:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ email: () => { error: boolean; }; }'.
  No index signature with a parameter of type 'string' was found on type '{ email: () => { error: boolean; }; }'.ts(7053)

The target method that I am trying to invoke is shown below:

export class PatientFormService {

  static formProps = {
    "email": () => {
      console.log('email control');
      return { error: true };
    }
  }
}

In my attempt in TypeScript Playground, I encounter a similar issue:

TypeScript Playground Link

UPDATE:

I attempted the following modification:

createFormControl(formControls:PatientFormProps[]):void {
    for (const control  of formControls) {
      const newPatientFormControl = new FormControl();
      if (control.options.required) {
        const { key } = { ...control };//fetching only necessary key
       newPatientFormControl.setValidators([Validators.required, PatientFormService.formProps[key as const]]);//does not work
      }
      this.patientForm.addControl(control.key, newPatientFormControl);
    }
    console.log(this.patientForm);
  }

Answer №1

To correct this issue, make sure to include a const assertion:

export class PatientFormService {
  static formProps = {
    "email": () => {
      console.log('email control');
      return { error: true };
    }
  };
}

const value = { label: 'email' } as const;

PatientFormService.formProps[value.label]();

Answer №2

If you want to approach it differently, consider creating a union type for all allowed values and using that to restrict the type of value in your scenario (for instance, { label: 'email' } would have the type { label: string }).

One way to accomplish this is by defining a utility type like the following:

type FunctionNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]

You can view an updated version of your example on TS Playground, where I've used this method to address the error message about implicitly having an 'any' type. Also, here's another TS Playground that resembles your original code more closely.

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

Module 'csstype' not found

I am diving into the world of React with TypeScript. After setting up react and react-dom, I also installed @types/react and @types/react-dom which all went smoothly. However, a pesky error message keeps popping up: ERROR in [at-loader] ./node_modules/@t ...

The function mustAsync onSuccess is not present in this type (typescript)

I currently have 2 mutations that are functioning well. However, I encountered an issue when attempting to implement onSuccess and invalidateQueries. The error message displayed is as follows: Property 'mutateAsync' does not exist on type '{ ...

I'm looking to find the Angular version of "event.target.value" - can you help me out?

https://stackblitz.com/edit/angular-ivy-s2ujmr?file=src/app/pages/home/home.component.html I am currently working on getting the dropdown menu to function properly for filtering the flags displayed below it. My initial thought was to replicate the search ...

Utilizing PrimeNG's p-dataView feature without repetitive FieldSets

Currently, I am utilizing p-dataView and I'm interested in implementing p-fieldset based on the application type. My goal is to prevent the fieldset from being duplicated when multiple instances occur. The scenario below illustrates one such case; how ...

Unlocking keys of JavaScript class prior to class initialization

My constructor was becoming too large and difficult to maintain, so I came up with a solution to start refactoring it. However, even this new approach seemed bulky and prone to errors. constructor(data: Partial<BusinessConfiguration>) { if(!d ...

Attempting to authenticate with Next.js using JWT in a middleware is proving to be unsuccessful

Currently, I am authenticating the user in each API call. To streamline this process and authenticate the user only once, I decided to implement a middleware. I created a file named _middleware.ts within the /pages/api directory and followed the same appr ...

Instantiate a fresh object using the new keyword followed by the Class constructor, and if desired,

I'm looking for a class that I can easily create new instances from and optionally assign properties using the constructor. For instance: class Person { name: string; age: number; constructor(props: {name?: string, age?: number}) { this.nam ...

Exploring the process of associating a string with a specific enum value in TypeScript

One scenario is if you receive a string value from the server and have an enum type with string values defined. In TypeScript, how can you convert the string value to the enum type? export enum ToolType { ORA= 'orange', ST= 'stone' , ...

Issue with rejecting a promise within a callback function in Ionic 3

Within my Ionic 3 app, I developed a function to retrieve a user's location based on their latitude and longitude coordinates. This function also verifies if the user has location settings enabled. If not, it prompts the user to switch on their locati ...

The component is failing to store its value within the database

I'm encountering an problem when attempting to save an option in the database. To address this issue, I created a component in Svelte called StatePicker that is responsible for saving US States. However, when I try to save it in the database using a ...

Can we define the input and return types for functions using httpsCallables?

I have implemented a callable function in my app to update user claims. The functions are written in Typescript and I have used an interface to define the required data shape for the function. My objective is to make it easier for any developer on the tea ...

Building a Dynamic Checkbox Validation Feature in Angular Using Data retrieved from an API

Currently, I have a function that retrieves and displays a list obtained from an API: displayEventTicketDetails() { this.Service .getEventTicketDetails().subscribe((data: any) => { this.eventTicketDetails = data.map(ticket => ticket. ...

Implementing JavaScript Code in TypeScript

Every JavaScript code should also be valid in TypeScript, but when attempting to run the following code snippet below, an error is triggered. Could someone convert this JavaScript code into TypeScript? Error: 20:9 - TS2531 Error: Object is possibly 'z ...

Setting a default value for the dropdown in Angular is essential for ensuring a smooth

<select [(ngModel)]="detail.State" (ngModelChange) ="onStateChange()" class="form-control"> <option [ngValue]="null" disabled selected>Select State</option> <option * ...

typescriptIs there a more efficient approach to typing optional values without a default value in

In my React application with TypeScript, I am using the following code to provide typed props: type ScheduleBoxContentProps = { desc: ReactNode, lottie: LottieProps, } & Partial<{className: string}>; I want the className prop to be optional ...

Develop an "Import Interface" using TypeScript

I have a large project with many files and I believe using an import object would be beneficial. For instance, consider having menu.ts at the top level that every program will refer to: import router from "./router/index"; import controllers from ...

Guide on implementing Regular Expressions in Directives for validation in Angular 8

Managing 8 different angular applications poses its unique challenges. In one of the applications, there is a directive specifically designed for validating YouTube and Vimeo URLs using regular expressions. Unfortunately, once the RegExp is declared, ther ...

Whenever I try to utilize async with React.FC in my React component, a TypeScript error is thrown

I am currently working on a React functional component called DashboardPage that utilizes async/await for fetching data, but I am running into a TypeScript error. The specific error message reads: 'Type '({ params }: DashboardPageProps) => Pro ...

Encountered an issue in React and Typescript where the argument type is not compatible with the parameter type 'EventListenerOrEventListenerObject'

One challenge I am facing is integrating Typescript into my React project: componentDidMount() { document.addEventListener('mousemove', this.handleMouseMove); } private handleMouseMove = (e: React.MouseEvent<HTMLElement>) => { appS ...

What is the most appropriate form to use, and what factors should be considered in determining

Incorporating generics in typescript allows me to create a generic function in the following manner: Choice 1 declare function foo1<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } Alternatively, I have the option to omit the seco ...