перекомпоновать с помощью StateHandlers и TypeScript, тип реализации утечки в компонент? - PullRequest
0 голосов
/ 03 мая 2018

Я пытаюсь обернуть функциональный компонент без сохранения состояния withStateHandlers из перекомпоновки. Я нахожу единственный способ сделать это, если я настрою реквизиты своего SFC для соответствия некоторым аспектам withStateHandlers, которые «просачиваются». Я делаю что-то не так или это недостаток типов восстановления?

Мой SFC:

interface IProps {
    className?: string;
    isEditing: boolean;
    toggleEditing: () => void;
}

const MyComponent: React.SFC<IProps> = ({ className, isEditing, toggleEditing }) => (
    <button className={className} onClick={toggleEditing}>{isEditing ? 'stop editing' : 'start editing'}</button>
);

export default MyComponent;

Отсюда я хочу обернуть это withStateHandlers:

import { withStateHandlers, StateHandlerMap, StateHandler } from 'recompose';
import MyComponent from '../components/myComponent';
interface IProps {
    className?: string;
}

interface IToggleEditingState {
    isEditing: boolean;
}

interface IToggleEditingStateUpdaters extends StateHandlerMap<IToggleEditingState> {
    toggleEditing: StateHandler<IToggleEditingState>
}

const withToggleEditState = withStateHandlers<IToggleEditingState, IToggleEditingStateUpdaters, IProps> (
    { isEditing: false },
    {
        toggleEditing: (state) => () => ({ isEditing: !state.isEditing })
    }
);

const StatefulMyComponent = withToggleEditState(MyComponent);

Но это не работает, я получаю эту ошибку во время компиляции:

(32,43): Argument of type 'StatelessComponent<IProps>' is not assignable to parameter of type 'ComponentType<IProps & IToggleEditingState & IToggleEditingStateUpdaters>'.
  Type 'StatelessComponent<IProps>' is not assignable to type 'StatelessComponent<IProps & IToggleEditingState & IToggleEditingStateUpdaters>'.
    Type 'IProps' is not assignable to type 'IProps & IToggleEditingState & IToggleEditingStateUpdaters'.
      Type 'IProps' is not assignable to type 'IToggleEditingStateUpdaters'.
        Types of property 'toggleEditing' are incompatible.
          Type '() => void' is not assignable to type 'StateHandler<IToggleEditingState>'.
            Type 'void' is not assignable to type 'Partial<IToggleEditingState> | undefined'.

Это связано с тем, что toggleEditing определено как () => void в подпорках MyComponent. Я исправляю это, а также получаю сообщение об ошибке отсутствующего индексатора.

Чтобы компилятор был доволен, мне нужно изменить IProps MyComponent на:

interface IProps {
    className?: string;
    isEditing: boolean;
    toggleEditing: (...payload: any[]) => any;
    [key: string]: any;
}

Мне нужно изменить toggleEditing, чтобы он соответствовал типу StateHandler<T>, как определено в @ types / Recompose. Мне также нужно добавить индексатор. Это происходит потому, что в @ types / Recompose withStateHandlers возвращает InferableComponentEnhancerWithProps<TOutter & TState &TUpdates, TOutter>, который в конечном итоге после того, как вы пройдете все типы, все еще ожидает индексатор для компонента.

Я заметил в тестах , что они определяют SFC, а затем упаковывают все это в одном месте. Так что тот факт, что SFC на самом деле предъявляет нечетные требования к опорам, не очевиден. Я хотел бы определить свой SFC самостоятельно, чтобы я мог использовать его в других ситуациях. Я просто перехожу за пределы ожидаемого варианта использования? Я что-то не так делаю?

...