所以我有一组基础组件,其道具类型设置为:
type SomeProps = {
// ... arbitrary prop types
theme: {
wrapper: string,
button: string,
// these are also kind of arbitrary
}
}
现在我有一个 HOC 将注入theme
道具,因此这个新创建的组件的用户不必/不应该传递theme
道具。测试表明以下代码不起作用(合并同一字段的类型)......
type A = { foo: number };
type B = A & { foo?: number };
const x: B = { foo: 2 };
无论如何,我编写了 HOC,但我不确定流类型在我描述的场景中是否有效。作为附加要求,新创建的组件仍然可以传递一个theme
应该与注入的 prop 合并的 prop theme
。这是 HOC 的代码:
// @flow
import withProps from 'recompose/withProps';
import setDisplayName from 'recompose/setDisplayName';
import wrapDisplayName from 'recompose/wrapDisplayName';
import classnames from 'classnames';
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 };
type OptionalThemePropType = {
[prop: string]: mixed,
theme?: ThemeType
}
function mergeTheme<T, U: T & { theme: ThemeType }>(
injectedTheme: ThemeType
): (BaseComponent: Component<T>) => Component<U> {
return BaseComponent => {
const Themed: Component<U> = withProps((ownProps: OptionalThemePropType) => {
let theme: ThemeType = injectedTheme;
if (ownProps && ownProps.theme) {
const ownTheme: ThemeType = ownProps.theme;
theme = Object
.keys(ownTheme)
.filter((key: string) => !!injectedTheme[key])
.reduce(
(accum: ThemeType, key: string) => {
accum[key] = classnames(ownTheme[key], injectedTheme[key]);
return accum;
},
{ ...ownTheme, ...injectedTheme }
);
}
return { theme };
})(BaseComponent);
setDisplayName(wrapDisplayName(BaseComponent, 'themed'))(Themed);
return Themed;
};
}
它是否正确?