Попытка составить несколько HOC (с помощью compose func), похоже, вообще теряет аннотации реквизита, как будто создание правильного HOC, не теряющего его, по умолчанию содержит обернутые (поэтому необязательные) реквизиты компонента.
Нашел несколько хороших обходных путей, чтобы HOC сохранил дополнительные реквизиты обернутых компонентов, используя JSX.LibraryManagedAttributes
псевдоним:
import React from 'react';
import { compose } from 'redux';
import { connect } from 'react-redux';
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
// wrapper
export interface WithThemeProps {
theme: string;
}
interface WrapperProps {
foo: string;
}
function withTheme<
C extends React.ComponentType<React.ComponentProps<C> & WithThemeProps>,
ResolvedProps = JSX.LibraryManagedAttributes<C, Omit<React.ComponentProps<C>, keyof WithThemeProps>>
>(component: C) {
return connect<WithThemeProps, void, WrapperProps & ResolvedProps>(() => ({
theme: 'theme',
}))(component as React.ComponentType);
}
// component with default props
interface Props extends WithThemeProps {
message: string;
required: string;
}
class Component extends React.Component<Props> {
static defaultProps = {
message: '',
};
render() {
return <div />;
}
}
// usage
const Wrapped = withTheme(Component);
const el = <Wrapped required="r" foo="f" />; // works
const Composed = compose(withTheme)(Component);
const HeavilyComposed = compose( withTheme, withTheme )(Component);
const x = <Composed required="r" foo="f" />; // wrapped works
const y = <HeavilyComposed required="r" foo="f" />; // error, props are lost altogether
Также я натолкнулся на интересную идею для модели compose
функция для этого конкретного сценария.Немного доработав исходный ответ, все реквизиты сохраняются, но также это делает их необходимыми, что я не ожидал:
const HeavilyComposed = compose( withTheme, withTheme )(Component);
// Type '{ required: string; foo: string; }' is missing the
// following properties from type 'Props': message, theme
const y = <HeavilyComposed required="r" foo="f" />;
declare function compose<A, R, R2>(
f1: (b: A) => React.ComponentType<R2>,
f2: (b: A) => React.ComponentType<R>
): <P>(c: React.ComponentType<P>) => React.ComponentType<P & R & R2>;
Как должна выглядеть функция compose для сохранения опциональных и опущенныхреквизит?