Reputation: 61
I need to create an utility function, which will be returning one of react component classes (not instances) depending on some condition. So the return type of the function should be generic (React.PureComponent)
import React from 'react';
class FooOne extends React.PureComponent {
render(): React.ReactElement {
return null;
}
}
class FooTwo extends React.PureComponent {
render(): React.ReactElement {
return null;
}
}
function getFooClass(condition: boolean): typeof React.PureComponent {
return condition ? FooOne : FooTwo;
}
const SomeFooClass = getFooClass(true);
const instance: React.PureComponent = new SomeFooClass();
code above is tended to be working (I still not understand why I need to use typeof React.PureComponent as return type for getFooClass, this was found experimentally), but typescript generates the following error for getFooClass:
Type 'typeof FooOne' is not assignable to type 'typeof PureComponent'.
Construct signature return types 'FooOne' and 'PureComponent<P, S>' are incompatible.
The types of 'props' are incompatible between these types.
Type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>' is not assignable to type 'Readonly<{ children?: ReactNode; }> & Readonly<P>'.
Type 'Readonly<{ children?: ReactNode; }> & Readonly<{}>' is not assignable to type 'Readonly<P>'.
Maybe this is kind of typescript bug or limitation?
Upvotes: 4
Views: 8187
Reputation: 414
Try something like
function getFooClass(condition: boolean): React.ComponentType {
// if FooOne and FooTwo have arguments you can use React.ComponentType<TArgs>
return condition ? FooOne : FooTwo;
}
usage should be like this
function render() {
const FooEl = getFooClass(true); // PascalCase is required
return <FooEl />
}
or simply return created instance
function getFooClass(condition: boolean): JSX.Element {
return condition ? <FooOne /> : <FooTwo />;
}
Upvotes: 4
Reputation: 5747
React.ReactNode should work in this case:
function getFooClass(condition: boolean): React.ReactNode {
return condition ? FooOne : FooTwo;
}
Upvotes: 2