如何为使用上下文更改道具的React组件键入/实现装饰器

时间:2018-12-06 17:05:43

标签: reactjs typescript

我想创建一个打字稿装饰器,以将子组件中的一些props从react上下文注入到子组件中,并且我希望它能正确键入:

1)从外部,无需提供额外的道具就可以渲染子组件

2)在子组件内部,我想声明额外的道具并像传入的那样使用它们。

这是我到目前为止提出的:

// props that I want the decorator to add
type AdditionalProps = {
  prop1: string;
  prop2: string;
};

// the props will be stored in the react context
const AdditionalPropsContext = React.createContext<AdditionalProps>({ prop1: "foo", prop2: "baz" });

// helper type to remove the additional props from another type
type GetOutputProps<T extends Partial<AdditionalProps>> = Pick<T, Exclude<keyof T, keyof AdditionalProps>>;

// this is my decorator/HOF
export function injectProps<InputProps extends Partial<AdditionalProps>>(Component: React.ComponentType<InputProps>): React.ComponentType<GetOutputProps<InputProps>> {
  return (props: GetOutputProps<InputProps>) => <AdditionalPropsContext.Consumer>
    {additionalProps => <Component {...props} {...additionalProps} />}
  </AdditionalPropsContext.Consumer>;
}

// this is the child component that I want to enhance
class ChildComponent extends React.Component<{ p1: string, prop1: string }> {
  public render() {
    return <div>{this.props.p1} {this.props.prop1}</div>;
  }
}

// using the function normally it seems to work fine, but only in ts 3.1, in 3.2 the function injectProps is not compiling
const ChildComponentWrapped = injectProps(ChildComponent);

// the decorator instead gives me an error
@injectProps
class ChildComponentInjected extends React.Component<{ p1: string, prop1: string }> {
  public render() {
    return <div>{this.props.p1} {this.props.prop1}</div>;
  }
}



// parent class that renders the child components (wrapped in the context provider)
class ParentComponent extends React.Component {
  public render() {
    return <AdditionalPropsContext.Provider value={{ prop1: "foooo", prop2: "baaaaaz" }}>
      {*/ somewhere in the subtree inside the provider, i render the child components /*}
      <ChildComponentInjected p1="asd" />  // this tells me that the component is missing the prop1 prop
      <ChildComponentWrapped p1="asd"/> // this works fine
    </AdditionalPropsContext.Provider>;
  }
}

1)为什么装饰器无法正常工作,而非装饰器版本运行良好?它是装饰器的限制吗?有可能实现类似的目标吗?

2)在打字稿3.1中,injectProps函数正确编译。在打字稿3.2中,我在

上收到错误消息
<Component {...props} {...additionalProps} />  

行。为什么?

顺便说一句:我使用的是最新的React类型(16.7)

更新:

关于我的第一个问题,似乎确实装饰器当前仅限于返回它们装饰的相同类型,react-redux的连接也存在相同的问题:

https://github.com/Microsoft/TypeScript/issues/4881

https://github.com/DefinitelyTyped/DefinitelyTyped/issues/9951

除了希望将来会得到改进之外,目前不确定该怎么做。

问题2仍然保持打开状态

0 个答案:

没有答案