我正在尝试扩展redux connect,以便它可以与特定的reducer/state一起用作decorator,这可能不是必需的,因为redux connect可以用作decorator,但是我很好奇为什么我不能让它按我想要的方式工作。
这是我用作装饰的hoc:

interface InjectedProps { userId: string; }
type ComponentType<P> = React.ComponentClass<P> | React.StatelessComponent<P>;
type StateToProps = (setting: ApplicationState) => InjectedProps;
export function withUserSetting(
  stateToProps?: StateToProps
): <P extends InjectedProps>(WrappedComponent: ComponentType<P>) => void {
  return <P extends InjectedProps>(Comp: ComponentType<P>) => {
    class NewComponent extends (Component || PureComponent)<P> {
      render() {
        return <Comp {...this.props} />;
      }
    }
    return connect(stateToProps)(NewComponent as any);
  };
}

它工作得很好,如果道具丢失,它会提醒我,这是因为它期望返回“injectedprops”类型:
reactjs - Typesafe React装饰器无法识别所传递函数的ReturnType-LMLPHP
但是,我想修改hoc,以便它可以根据“statetrops”的返回类型向我发出警报:
type AnyFunction = (...args: any[]) => any;
type ComponentType<P> = React.ComponentClass<P> | React.StatelessComponent<P>;
type StateToProps = (setting: ApplicationState) => { [key: string]: any };
export function withUserSetting<T extends AnyFunction>(
  stateToProps?: StateToProps
): <P extends ReturnType<T>>(WrappedComponent: ComponentType<P>) => void {
  return <P extends ReturnType<T>>(Comp: ComponentType<P>) => {
    class NewComponent extends (Component || PureComponent)<P> {
      render() {
        return <Comp {...this.props} />;
      }
    }
    return connect(stateToProps)(NewComponent as any);
  };
}

正如您所看到的,“injectedprops”不再是必需的,因此它可以有任何prop名称,而且我假设因为“returnType”的缘故,decorator应该自动识别prop s,并在没有为组件声明它时提醒我,但它没有任何效果:
reactjs - Typesafe React装饰器无法识别所传递函数的ReturnType-LMLPHP
装潢工作很好,但是,我没有一个类型的安全我正在寻找!
知道为什么没用吗?

最佳答案

在简化代码并更好地理解它之后,我设法使它工作,这是工作版本:

type ComponentType<P> = React.ComponentClass<P> | React.StatelessComponent<P>;
type MapStateToProps<T> = (setting: ApplicationState) => T;
export function withUserSetting<T>(mapStateToProps?: MapStateToProps<T>):
  <P extends T>(WrappedComponent: ComponentType<P>) => void {
  return <P extends T>(WrappedComponent: ComponentType<P>) => {
    return connect(mapStateToProps)(WrappedComponent as any);
  };
}

现在可以这样使用:
@withUserSetting((state) => ({ userId: state.userSetting.userId }))

或者像这样:
@withUserSetting<UserProps>((state) => ({ userId: state.userSetting.userId }))

在这两种方式中,如果声明中缺少一个属性,则会引发错误。

关于reactjs - Typesafe React装饰器无法识别所传递函数的ReturnType,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54009189/

10-13 04:22