1 | import React, {ComponentType} from 'react';
|
2 | import hoistStatics from 'hoist-non-react-statics';
|
3 |
|
4 | export type ReactComponent<P> = ComponentType<P>;
|
5 | export type ComponentClass = React.ComponentClass<any>;
|
6 |
|
7 | export type WrappingFunction = (
|
8 | Component: ReactComponent<any>,
|
9 | ) => ReactComponent<any>;
|
10 |
|
11 | export default function compose<Props>(
|
12 | ...wrappingFunctions: WrappingFunction[]
|
13 | ) {
|
14 | return function wrapComponent<ComposedProps, C>(
|
15 | OriginalComponent: ReactComponent<ComposedProps> & C,
|
16 | ): ReactComponent<Props> & C {
|
17 | let result: ReactComponent<ComposedProps>;
|
18 |
|
19 | if (wrappingFunctions.length === 0) {
|
20 | result = OriginalComponent;
|
21 | } else {
|
22 | result = wrappingFunctions.reduce(
|
23 | (wrappingFunctionA, wrappingFunctionB) => {
|
24 | return (WrappingComponent: ReactComponent<any>) =>
|
25 | wrappingFunctionA(wrappingFunctionB(WrappingComponent));
|
26 | },
|
27 | )(OriginalComponent);
|
28 | }
|
29 |
|
30 | return hoistStatics(
|
31 | result as ComponentClass,
|
32 | OriginalComponent as ComponentClass,
|
33 | ) as ReactComponent<Props> & C;
|
34 | };
|
35 | }
|