1
所以我有一組具有它的道具類型設定爲基本組件:定義的正確類型的HOC注入道具
type SomeProps = {
// ... arbitrary prop types
theme: {
wrapper: string,
button: string,
// these are also kind of arbitrary
}
}
現在我有這回事注入theme
道具,使用戶的HOC這個新創建的組件不需要/不應該通過theme
道具。測試結果表明,下面的代碼將無法工作,雖然(類型同場的合併)...
type A = { foo: number };
type B = A & { foo?: number };
const x: B = { foo: 2 };
無論如何,我寫的HOC,但我不知道流類型的場景中工作我描述過。作爲附加要求,新創建的組件仍然可以通過theme
支柱,該支柱應與注入的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;
};
}
這是正確的嗎?