Flowtype 未知类型的流有界多态性
我正在尝试使用一个函数,该函数将React组件和对象作为参数,并使用正确的流类型。因此,React Component参数应该期望类型为Flowtype 未知类型的流有界多态性,flowtype,Flowtype,我正在尝试使用一个函数,该函数将React组件和对象作为参数,并使用正确的流类型。因此,React Component参数应该期望类型为P的props,其中P应该具有属性theme,该属性属于推断类型V。我知道V是字符串对象,但它仍然可以是不同的类型(即{button:string}不同于{checkbox:string})。第二个参数的类型应为V 函数的要点是获取一个需要proptheme(它只是该React组件的字符串对象)的React组件,并使用第二个参数作为该prop,返回一个新的Rea
P
的props,其中P
应该具有属性theme
,该属性属于推断类型V
。我知道V
是字符串对象,但它仍然可以是不同的类型(即{button:string}
不同于{checkbox:string}
)。第二个参数的类型应为V
函数的要点是获取一个需要proptheme
(它只是该React组件的字符串对象)的React组件,并使用第二个参数作为该prop,返回一个新的React组件,该组件不需要该theme
prop(因为已经给出了它)
我做了几次尝试,但仍然没有得到一些工作
/* @flow */
type FunctionComponent<P> = (props: P) => ?React$Element<any>;
type ClassComponent<D, P, S> = Class<React$Component<D, P, S>>;
type Component<P> = FunctionComponent<P> | ClassComponent<any, P, any>;
type ThemeType = { [className: string]: string };
function mergeTheme<P: { theme: ThemeType }, V: $PropertyType<P, 'theme'>>(
BaseComponent: Component<P>,
injectedTheme: V
): FunctionComponent<$Diff<P, { theme: V }>> {
const ThemedComponent = ownProps => <BaseComponent {...ownProps} theme={injectedTheme} />;
ThemedComponent.displayName = 'Themed(' + BaseComponent.displayName + ')';
return ThemedComponent;
}
/*@flow*/
类型FunctionComponent=(道具:P)=>?React$元素
我真正的目标实际上是让新的React组件接受一个可选的主题
参数,然后我将该参数与上面示例中的injectedTheme
合并,但首先是小步操作。目前看来效果不错。但不确定它是否正确:
type FunctionComponent<P, C> = (props: P, context: C) => ?React$Element<any>;
type ClassComponent<D, P, S> = Class<React$Component<D, P, S>>;
declare function mergeTheme<P: { theme: *, [propName: any]: any }, V: $PropertyType<P, 'theme'>>(
BaseComponent: ClassComponent<*, P, *>,
injectedTheme: V
): FunctionComponent<$Diff<P, { theme: V }> & { theme?: $Shape<V> }, *>;
declare function mergeTheme<P: { theme: *, [propName: any]: any }, V: $PropertyType<P, 'theme'>>(
BaseComponent: FunctionComponent<P, *>,
injectedTheme: V
): FunctionComponent<$Diff<P, { theme: V }> & { theme?: $Shape<V> }, *>;
function mergeTheme(BaseComponent, injectedTheme) {
const ThemedComponent = ownProps => {
let theme = injectedTheme;
if (ownProps && ownProps.theme) {
const ownTheme = ownProps.theme;
theme = Object.keys(ownTheme)
.filter(key => !!injectedTheme[key])
.reduce((accum, key) => {
accum[key] = classnames(ownTheme[key], injectedTheme[key]);
return accum;
}, { ...ownTheme, ...injectedTheme });
}
return <BaseComponent {...ownProps} theme={theme} />;
};
const currName = BaseComponent.displayName || BaseComponent.name;
ThemedComponent.displayName = `Themed(${currName})`;
return ThemedComponent;
}
typefunctioncomponent=(props:P,context:C)=>?React$Element这似乎目前运行良好。但不确定它是否正确:
type FunctionComponent<P, C> = (props: P, context: C) => ?React$Element<any>;
type ClassComponent<D, P, S> = Class<React$Component<D, P, S>>;
declare function mergeTheme<P: { theme: *, [propName: any]: any }, V: $PropertyType<P, 'theme'>>(
BaseComponent: ClassComponent<*, P, *>,
injectedTheme: V
): FunctionComponent<$Diff<P, { theme: V }> & { theme?: $Shape<V> }, *>;
declare function mergeTheme<P: { theme: *, [propName: any]: any }, V: $PropertyType<P, 'theme'>>(
BaseComponent: FunctionComponent<P, *>,
injectedTheme: V
): FunctionComponent<$Diff<P, { theme: V }> & { theme?: $Shape<V> }, *>;
function mergeTheme(BaseComponent, injectedTheme) {
const ThemedComponent = ownProps => {
let theme = injectedTheme;
if (ownProps && ownProps.theme) {
const ownTheme = ownProps.theme;
theme = Object.keys(ownTheme)
.filter(key => !!injectedTheme[key])
.reduce((accum, key) => {
accum[key] = classnames(ownTheme[key], injectedTheme[key]);
return accum;
}, { ...ownTheme, ...injectedTheme });
}
return <BaseComponent {...ownProps} theme={theme} />;
};
const currName = BaseComponent.displayName || BaseComponent.name;
ThemedComponent.displayName = `Themed(${currName})`;
return ThemedComponent;
}
type FunctionComponent=(props:P,context:C)=>?React$Element
type Theme = {|
someClass: string,
anotherClass: string
|};
type Props = { someProp: string, theme: Theme };
const SomeComponent = (props: Props) => <div className={props.theme.someClass}>{props.someProp}</div>;
const ThemedComponent = mergeTheme(SomeComponent, { someClass: 'world', anotherClass: 'idhgo' });
// The line below should work but instead flow complains
const el1 = <ThemedComponent someProp="hello" theme={{ someClass: 'hello' }} />
47: type Props = { someProp: string, theme: Theme };
^ property `anotherClass`. Property not found in
52: const el1 = <ThemedComponent someProp="hello" theme={{ someClass: 'poop' }} />
^ object literal