I'm creating a bunch of components with some common functions inside, one of them is the one that handles rendering. Simplified, it looks like this:
const render = (
instance: React.Component<{}, {flag: boolean}>,
cb: () => React.ReactNode
) => instance.state.flag ? cb() : '';
class Test extends React.Component<{}, {flag: boolean}> {
state = {flag: true};
render() { return render(this, () => '') }
}
TypeScript, although, is not happy with this setup and says: 'render' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. Personally, I can't see this reference.
As a possible clue, if I rewrite this code this way:
const render = (
state: {flag: boolean},
cb: () => React.ReactNode
) => state.flag ? cb() : '';
class Test extends React.Component<{}, {flag: boolean}> {
state = {flag: true};
render() { return render(this.state, () => '') }
}
...all works well, but I really want to use the component itself, due to some complexities left out of sight for now.
What's the problem? Can I do something with this common function so that TypeScript doesn't argue?
UPD: a bit of testing let me created the example which is a bit more close to the one needed:
type Component<T> = React.Component<{}, {flag: T}>
const render = <T>(
instance: Component<T>,
cb: () => React.ReactNode
) => instance.state.flag ? cb() : '';
class Test extends React.Component<{}, {flag: boolean}> {
state = {flag: true};
render() {
const result = render(this, () => '');
return result;
}
inner = () => 'test';
}
The main point here is the fact that external render function is generic, and instance type depends on the generic parameter, so that TypeScript is unable to substitute the proper parameter in place of T. Is it possible to help him without losing type-safety?