Typescript: составление HOC, обертывающих компоненты с defaultProps в React - PullRequest
0 голосов
/ 19 февраля 2019

Попытка составить несколько 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 для сохранения опциональных и опущенныхреквизит?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...