What is the process for invoking instance methods dynamically in TypeScript?

There is an object in my possession and the goal is to dynamically invoke a method on it.

It would be ideal to have typechecking, although that may prove to be unattainable. Unfortunately, the current situation is that I cannot even get it to compile:

  const key: string = 'someMethod'
  const func = this[key]
  func(msgIn)

leads to the following error message...

Element implicitly has an 'any' type 
because expression of type 'any' can't be used 
to index type 'TixBot'.

I experimented with other type options but none were successful.

  const key: any = cmd.func
  const func: any = this[key]

Aside from @ts-ignore, are there alternative solutions? I am considering utilizing .call() or bind as potential workarounds?

Answer №1

When using Typescript, it will throw an error if it cannot verify that the string being used is a valid member of the class. An example of this working correctly would be:

class MyClass {
    methodA() {
        console.log("A")
    }
    methodB() {
        console.log("B")
    }

    runOne() {
        const random = Math.random() > 0.5 ? "methodA" : "methodB" // random is typed as "methodA" | "methodB"
        this[random](); //ok, since random is always a key of this
    }
}

In the above examples, omitting the explicit type annotation from a constant will give you the literal type and enable you to use the const as an index into this.

You can also specify the string as keyof Class:

class MyClass {
    methodA() {
        console.log("A")
    }
    methodB() {
        console.log("B")
    }

    runOne(member: Exclude<keyof MyClass, "runOne">) { // exclude this method
        this[member](); //ok
    }
}

If you already have a string, you can use an assertion to keyof MyClass, although this may not be as type safe (this[member as keyof MyClass] where let member: string)

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

When working with formControlName in Angular Material 2, the placeholder may overlap the entered value

After updating my application with angular-cli to angular/material (2.0.0-beta.11) and angular (4.4.4), I noticed that every placeholder in the material input fields overlaps the value when provided with formControlName in reactive forms. However, when usi ...

Displaying Firebase values in an Angular 2 list is a breeze

Here is the functionality to load, add, and mark ToDo as Finished: todos: FirebaseListObservable<any>; ngOnInit(){ this.todos = this._af.database.list('todos') } addTodo(newTodo: string){ this.todos.push({ ...

Problem with timing in token interceptor and authentication guard due to injected service

Currently, I am facing an issue where I need to retrieve URLs for the auth service hosted on AWS by reading a config.json file. In order to accomplish this, I created a config service that reads the config file and added it as a provider in app.module. Eve ...

"The process of logging in to Facebook on Ionic app speeds up by bypassing

I'm facing a minor issue with Facebook login in Ionic. I've tried using Async - Await and various other methods to make it wait for the response, but nothing seems to work. The login function is working fine, but it's not pausing for me to p ...

The value returned by Cypress.env() is always null

Within my cypress.config.ts file, the configuration looks like this: import { defineConfig } from "cypress"; export default defineConfig({ pageLoadTimeout: 360000, defaultCommandTimeout: 60000, env: { EMAIL: "<a href="/cdn-cgi/ ...

The ViewChild from NgbModalModule in @ng-bootstrap/ng-bootstrap for Angular 6 is causing the modal to return as

I have successfully integrated ng bootstrap into my project, specifically utilizing the modal module to display a contact form. The form includes input fields for email and message, as well as a submit button. You can find the ngbootstrap module I am using ...

Creating a personalized state object containing unresolved promises in React Native utilizing axios inside a custom React Hook

I'm currently in the process of creating a custom state within a custom Hook for React Native (non-Expo environment). The state I am working on looks like this: interface ResponseState { api1: { error: boolean; errorMsg?: string; ...

Execute the render function of the components that have been passed as

I've been grappling with a challenge lately - figuring out how to invoke a passed component's render function within another function. Let's say I have two functions named A and B: export const A = (value: any) => { return ( <div& ...

The state is accurate despite receiving null as the return value

I'm feeling a bit lost here. I have a main component that is subscribing to and fetching data (I'm using the redux dev tools to monitor it and it's updating the state as needed). In component A, I am doing: public FDC$ = this.store.pipe(sel ...

Design an array specifically for runtime using a union type

Imagine I have the following union type: type Browser = 'Chrome' | 'Firefox' I am looking to convert this into an array: const browsers = /* code to change Browser type into ['Chrome', 'Firefox'] The goal is to u ...

"Setting up a schema in TypeORM when connecting to an Oracle database: A step-by-step guide

As a newcomer to TypeORM, I'm using Oracle DB with Node.js in the backend. Successfully connecting the database with TypeORM using createConnection(), but struggling to specify the schema during connection creation. One workaround is adding the schem ...

The character 'T' cannot be assigned to the data type 'number'

When working with an optional type argument function RECT(T), I encountered a situation where I need to check if the argument is an instance of date. If it is, I convert it to a number; if not, I use the number directly. However, I keep getting an error ...

struggling to access the value of [(ngModel)] within Angular 6 component

When working in an HTML file, I am using ngModel to retrieve a value that I want to utilize in my component. edit-customer.component.html <input id="userInfoEmail" type="text" class="form-control" value="{{userInfo.email}}" [(ngModel)]="userInfo.email ...

The declaration file for the 'react' module could not be located

I was exploring Microsoft's guide on TypeScript combined with React and Redux. After executing the command: npm install -S redux react-redux @types/react-redux I encountered an error when running npm run start: Type error: Could not find a decla ...

Encountering issues with managing CometD channels within Angular 2

After dabbling in Angular2 and Typescript, I decided to challenge myself by creating an application using plain javascript with the CometD library. The goal of this app was to retrieve data from a CometD channel and present it to the user in some way. So, ...

Navigating SSL certificate prompts in Protractor

Our programs utilize SSL certificates and we are unable to bypass Chrome's prompt for selecting a certificate. We would be satisfied with simply choosing the one certificate needed. Attempts have been made using this code: capabilities: { browser ...

Passing the value of the attribute from event.target as a parameter in a knockout click event

I have been exploring knockout events and am currently working on a functionality involving three buttons ("Packers", "Trail Blazers", and "Dodgers") within a div. Each button is associated with a data-league attribute of "NFL", "NBA", and "MLB," respectiv ...

Changing {number, Observable<string>} to Observable<number, string> is a necessary transformation to be made

Is there a way to convert an array of objects with the following structure: { id: number, data: Observable<string> } into an array of objects with this structure: Observable<{id: number, data: string}> using only RxJS operators? ...

a helpful utility type for extracting a union from a constant array of strings

I create string arrays using const assertions and then use them to generate union types. const elements = ["apple", "banana", "orange"] as const; type elementsUnion = typeof elements[number]; // type elementsUnion = "appl ...

Incorporating a unique variant with Tailwind called "

I'm currently struggling with inputting the configuration file for Tailwind. Despite my efforts, I cannot seem to get it right. The code appears correct to me, but I am unsure of what mistake I might be making. Below is the snippet of my code: import ...