reactjs - Typesafe React 装饰器无法识别传递函数的 ReturnType

标签 reactjs typescript decorator

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

这是我用作装饰器的 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);
  };
}

它工作正常,如果 Props 丢失它会提醒我,那是因为它期望返回类型为“InjectedProps”:

enter image description here

但是,我想修改 hoc,以便它可以根据“stateToProps”的返回类型提醒我:

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”装饰器应该自动识别 Prop 并在未为组件声明时提醒我,但是它没有任何效果:

enter image description here

装饰器工作正常,但是,我没有我正在寻找的类型安全! 知道为什么它不起作用吗?

最佳答案

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

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/

相关文章:

javascript - 跨 React 组件共享数据

reactjs - 使用 TypeScript 编写 React 高阶组件

javascript - 开 Jest + react : IntersectionObserver mock not working?

python - pygame.init() 似乎没有在装饰器中被调用

javascript - 什么是react js的学习方式?

reactjs - React, typescript 属性 'setState'在类型中丢失

arrays - 如何跨嵌套数组过滤 JSON 对象数组

angular - 在 Angular 7 中验证图像尺寸

python - 如何使用装饰器和线程返回函数值

c++ - 是否可以从可变参数模板调用多个基类构造函数?