问题
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