我想创建一个打字稿装饰器,以将子组件中的一些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仍然保持打开状态