Flowtype 未知类型的流有界多态性

Flowtype 未知类型的流有界多态性,flowtype,Flowtype,我正在尝试使用一个函数,该函数将React组件和对象作为参数,并使用正确的流类型。因此,React Component参数应该期望类型为P的props,其中P应该具有属性theme,该属性属于推断类型V。我知道V是字符串对象,但它仍然可以是不同的类型(即{button:string}不同于{checkbox:string})。第二个参数的类型应为V 函数的要点是获取一个需要proptheme(它只是该React组件的字符串对象)的React组件,并使用第二个参数作为该prop,返回一个新的Rea

我正在尝试使用一个函数,该函数将React组件和对象作为参数,并使用正确的流类型。因此,React Component参数应该期望类型为
P
的props,其中
P
应该具有属性
theme
,该属性属于推断类型
V
。我知道
V
是字符串对象,但它仍然可以是不同的类型(即
{button:string}
不同于
{checkbox:string}
)。第二个参数的类型应为
V

函数的要点是获取一个需要prop
theme
(它只是该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