I'm expecting React components like so:
class MySetting extends React.Component<{}> {
static name = 'My Setting';
render() {
return (<div>{'setting here'}</div>);
}
}
class Widget extends React.Component<{}> {
static settings = [ MySetting ]
render() {
return (<div>{'widget here'}</div>);
}
}
And I'd like to make a flow definition for them that essentially mean:
namesettings which is of the above typeHow do I do this? I've tried a couple things like:
interface Settings {
name: string;
}
export type SettingsComponent = React.ComponentType<Object> & Settings
interface Widget {
settings: Array<SettingComponent>;
}
export type WidgetComponent = React.ComponentType<Object> & Widget
Or
declare class SettingsComponent<Props, State = void> extends React$Component<Props, State> {
static name: string;
}
declare class WidgetComponent<Props, State = void> extends React$Component<Props, State> {
static settings: Array<Class<SettingsComponent<any, any>>>
}
But they inevitably throw various flow errors that are awkward to decipher. Is there a generally accepted way of doing this?
Looks like with some more research I found a solution (using [email protected]).
The answer is flow's $Subtype<T> utility type:
export type SettingsComponent = {
name: string;
} & $Subtype<React.ComponentType<Object>>
export type VisualizationComponent = {
settings: Array<SettingsComponent>;
} & $Subtype<React.ComponentType<Object>>
Though I'll add that while my previous flow errors are gone and errors do show up when using a component with missing static fields or accessing non-existent fields, my editor (Atom + Nuclide) doesn't show tooltips for the type anymore.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With