I'm writing a React app with TypeScript. My component's state looks like this:
type UploadState = {
...
modal: string | null
...
}
In my render I have:
render() {
return <div>{this.renderModal()}</div>
}
somewhere in the code I have:
this.setState({ modal: 'mappingModal' })
and finally renderModel is:
renderModal = () => {
if (this.state.modal === null) {
return
}
return this[modal as keyof this]() //It doesn't work
}
I EXPECT to have the return value of mappingModal:
mappingModal = () => {
return <h1>Some text or whatever!</h1>
}
But I get this error because of () in this[modal as keyof this]() :
Cannot invoke an expression whose type lacks a call signature.
Type '{}' has no compatible call signatures.ts(2349)
And if I remove () I get this error in the browser:
Warning: Functions are not valid as a React child.
This may happen if you return a Component instead of <Component /> from render.
Or maybe you meant to call this function rather than return it.
Any solution?
UPDATE (POTENTIAL ANSWER)
It seems if I use this[modal as keyof Upload]() - and Upload is my component name of course - I'll not have any problem. Hopefully it'll not cause any future bug
this[modal as 'mappingModal']()if'mappingModal'is a member ofthisshould work. If you have a set of functions onthisthat have the same signature, typingmodala union of those function names should work ..modalin advance. So I can't say something likethis[modal as 'mappingModal'](). Your solution works, but I'm looking for something more generickeyof thisis troublesome but the idea in whole doesn't look good. Why would a component allow to call any if its methods? It would allowrenderthen, this would hang a browser. In casemodalcan depend on user input, this is security problem and design problem otherwise.keyof thisis not fully known so it acts like a hidden type parameter to the class, derived classes could add to it sothis[keyof this]does not get resolved inside the class since you don't really know what the type ofthisis. But I agree the design has a code smell about it ..thisis. Actually, this likely should bekeyof typeof this. Doesn't work this way. Could be a limitation or a bug.