重构withStateHandlers和TypeScript,实现类型泄漏到组件?

时间:2018-05-03 19:42:47

标签: reactjs typescript definitelytyped recompose

我正在尝试用重构的withStateHandlers包装无状态功能组件。我发现我能做到这一点的唯一方法就是如果我调整我的SFC的道具来匹配withStateHandlers的某些“泄漏”的方面。我做错了什么,或者这是重组类型的缺陷吗?

我的证监会:

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在MyComponent的道具中定义为() => void。我解决了这个问题,并且还得到了一个关于缺少索引器的错误。

为了让编译器满意,我需要将MyComponent的IProp更改为:

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

我必须更改toggleEditing以匹配@ types / recompose中定义的StateHandler<T>的类型。我还需要添加索引器。这看起来是因为在@ types / recompose中,withStateHandlers返回InferableComponentEnhancerWithProps<TOutter & TState &TUpdates, TOutter>,最终在您完成所有类型之后,仍然需要组件上的索引器。

我在tests中注意到,他们正在定义SFC,然后将它们全部包装在一个地方。因此,证监会实际上有奇数要求的事实并不明显。我想自己定义我的SFC,所以我可以在其他情况下重用它。我是否只是超越了预期的用例?我做错了吗?

0 个答案:

没有答案