how to dynamically call instance methods in typescript?

别等时光非礼了梦想. 提交于 2021-01-02 06:30:21

问题


I have an object and I want to dynamically call a method on it.

Having typechecking would be nice but that maybe impossible. But I can't even get it to compile at all currently:

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

gives me this error...

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

I tried some other type options without success.

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

Apart from @ts-ignore how could I solve this? I was wondering if I can use .call() or bind to somehow work around it?


回答1:


Typescript will error if it can't check that the string used is a valid member of the class. This for example will work:

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 samples above removing the explicit type annotation from a constant should give you the literal type and allow you to use the const to index into this.

You could also type 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 using an assertion to keyof MyClass is also an option although this is not as type safe (this[member as keyof MyClass] where let member: string)




回答2:


For example, some syntetic code

  class Auth extends React.Component {
    validateField(fieldName: string) {
      const validator = this[`${fieldName}IsValid` as keyof Auth]
      ...
    }

    emailIsValid() {
      return /.+@.+/.test(this.state.email)
    }

    passwordIsValid() {
      return /.{3,}/.test(this.state.password || '')
    }

    render() {
      return (
        <form>
          <input name="email" onChange={this.validateFormField('email')} .../>
          <input name="password" onChange={this.validateFormField('password')} .../>
        </form>
      )
    }
  }


来源:https://stackoverflow.com/questions/56894440/how-to-dynamically-call-instance-methods-in-typescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!