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

Tips for sending an Object within a multipart/form-data request in Angular without the need for converting it to a string

To successfully pass the object in a "multipart/form-data" request for downstream application (Java Spring) to receive it as a List of custom class objects, I am working on handling metadata objects that contain only key and value pairs. Within the Angula ...

The parameter type 'router' cannot be replaced with the type 'typeof ...'. The 'param' property is not included in the type 'typeof'

I'm currently working on a node application using TypeScript and have set up routing in a separate file named 'route.ts' import home = require('../controller/homeController'); import express = require('express'); let ro ...

What is the best way to represent a directory structure in JSON using a C# data type?

My directory structure is as follows: v1 file1.txt file2.txt common common.txt I need to create a C# function that can traverse this directory structure and generate JSON output. The expected JSON format is like this: { "v1&qu ...

What is the best way to handle closing popups that have opened during an error redirection

In my interceptor, I have a mechanism for redirecting the page in case of an error. The issue arises when there are popups already open, as they will not automatically close and the error page ends up appearing behind them. Here's the code snippet re ...

Updating from React 17 to React 18 in Typescript? The Children of ReactNode type no longer supports inline conditional rendering of `void`

When using the React.ReactNode type for children, inline conditional renders can cause failures. Currently, I am utilizing SWR to fetch data which is resulting in an error message like this: Type 'false | void | Element | undefined' is not assig ...

Anticipate that the typescript tsc will generate an error, yet no error was encountered

While working in the IDE to edit the TypeScript code, an issue was noticed in checkApp.ts with the following warning: Argument type { someWrongParams: any } is not assignable to parameter type AddAppToListParams. Surprisingly, when running tsc, no error ...

Dynamic getter/setter in Typescript allows for the creation of functions

I'm facing a challenge in making Typescript automatically infer types for dynamically created getter and setter functions. In my code, I have a class called MyClass which contains a map of containers: type Container = { get: () => Content s ...

Error: Failed to load chunk 552 due to chunk loading issue

Currently in the process of migrating Angular 12 to version 13. The migration itself was successful, however, upon running the project in the browser post a successful build, the application fails to display. On checking the console, I encountered the foll ...

Error in Angular SSR: Build failed due to project reference without "composite" setting set to true

Currently facing an issue while developing an Angular App with SSR. When using npm run build:ssr, the following errors are displayed: ERROR in [...]/tsconfig.json [tsl] ERROR TS6306: Referenced project '[...]/tsconfig.app.json' must have se ...

Which superclass does ReadonlyArray extend from?

Looking at this TypeScript code snippet: const arr: ReadonlyArray<string> = [ "123", "234" ]; arr.push("345"); An error is thrown by the TS compiler: Property 'push' does not exist on type 'ReadonlyArray<string>&apo ...

The issue of returning a boolean value in an rxjs function leading to failure

Hey there, I am currently learning about rxjs and I want to create an observable that returns either true or false. This is my attempted code: checkLoggedIn(): Observable<boolean> { // Check with the server if the user is logged in if(this._tok ...

What is the reason behind the narrowing of the type by indexing into a mapped type?

This question is inspired by an amazing answer found here: My curiosity lies in why the indexing works in the mapped type trick. Let's illustrate with an example: type MyData = { a: { alpha: string; }; b: { beta: number; } } type ...

Problems arising from the layout of the PrimeNG DataView component when used alongside Prime

I've been working with a PrimeNG DataView component that requires the use of PrimeFlex's flex grid CSS classes to set up the grid structure. One of their examples includes the following instructions: When in grid mode, the ng-template element ...

Can the script be loaded into a TypeScript file?

I'm currently in the process of integrating this script tag into my Angular 2 project, but I'm searching for a way to incorporate it into the typescript file so that I can access its methods within the .ts file. <script type="text/javascript" ...

Looking for a button that can be toggled on and off depending on the input fields

Even after adding useEffect to my code, the button component remains disabled unless the input fields are filled. It never enables even after that. export default function Page() { const [newPassword, setNewPassword] = useState(''); const [conf ...

An error occurred while trying to add a property to an array because the object is not extensible: TypeError -

In my code, there is an object named curNode with the following structure: { "name": "CAMPAIGN", "attributes": {}, "children": [] } I am attempting to add a new node to the object like this: curNode!.children!.push({ name: newNodeName, ...

The object may be null even after being enclosed in an if statement

In my Vue component, I have implemented the following method: dataURLtoBlob(dataurl: string): Blob { const arr: string[] = dataurl.split(","); if (arr) { if (arr[0]) { const mime = arr[0].match(/:(.*?);/)[1]; ...

Problem encountered when attempting to retrieve information from a web service in Angular 4

I am currently attempting to retrieve data from a web service API. However, all I can see is the data on the console. The web service requires an ID, so I input the ID first and then proceed to obtain the data related to that ID within the web service us ...

Tips for managing variables to display or hide in various components using Angular

In this example, there are 3 main components: The first component is A.component.ts: This is the parent component where an HTTP call is made to retrieve a response. const res = this.http.post("https://api.com/abcde", { test: true, }); res.subscribe((r ...

The entire DOM in Angular2+ flickers upon loading a component using ngFor

I am facing an issue where, after a user clicks on an item to add it to a list and then renders the list using ngFor, there is a flickering effect on the screen/DOM. The strange thing is that this flicker only happens after adding the first item; subsequen ...