我正在尝试制作一个高阶组件,该组件从当前上下文中获取一个函数并将其注入到包装组件中的prop中,并且仍然保持Props
接口。
我像这样包裹它:
interface Props extends AsyncRequestHandlerProps {
bla: string;
}
class MyComponent extends React.Component<Props> {
// ....
}
export default withAsyncRequestHandler(MyComponent)
我已经这样定义了withAsyncRequestHandler
export interface AsyncRequestHandlerProps {
asyncRequestHandler: <T>(promise: Promise<T>) => Promise<T | null>;
}
type PropsWithoutInjectedHandler<P> = Omit<P, keyof AsyncRequestHandlerProps>;
export function withAsyncRequestHandler<P>(Component: React.ComponentType<P>) {
return class ComponentWithAsyncRequestHandler extends React.Component<
PropsWithoutInjectedHandler<P>
> {
static contextType = AsyncHandlerContext;
context!: AsyncHandlerContext | null;
render = () => {
const asyncRequestHandler: <T>(
promise: Promise<T>
) => Promise<T | null> = (promise) => {
if (this.context === null) {
throw new Error(
"withAsyncRequestHandler should only wrap components that are mounted inside <AsyncHandler />."
);
}
return AsyncRequest(promise, this.context);
};
const { ...props } = this.props;
return (
<Component
{...props}
asyncRequestHandler={asyncRequestHandler}
></Component>
);
};
};
}
MyComponent
道具和bla
道具都是asyncRequestHandler
的直接签名。我想要的是包装器HOC将仅使用bla
道具返回组件签名,因为已经注入了asyncRequestHandler
。
此HOC的外部接口似乎正常工作,在安装包装好的组件时,我可以从打字稿中获取剩余的道具。
但是在HOC内部,我得到一个错误:
我当前的代码在我将<Component>
安装到render()
的那一行上给出了此错误。
Type 'Readonly<Pick<P, Exclude<keyof P, "asyncRequestHandler">>> & { asyncRequestHandler: <T>(promise: Promise<T>) => Promise<T | null>; children?: ReactNode; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
Type 'Readonly<Pick<P, Exclude<keyof P, "asyncRequestHandler">>> & { asyncRequestHandler: <T>(promise: Promise<T>) => Promise<T | null>; children?: ReactNode; }' is not assignable to type 'P'.
'P' could be instantiated with an arbitrary type which could be unrelated to 'Readonly<Pick<P, Exclude<keyof P, "asyncRequestHandler">>> & { asyncRequestHandler: <T>(promise: Promise<T>) => Promise<T | null>; children?: ReactNode; }'.ts(2322)
我猜问题出在Omit<P, keyof AsyncRequestHandlerProps>
构造及其用法上?
答案 0 :(得分:1)
根据https://github.com/Microsoft/TypeScript/issues/28938#issuecomment-450636046,这是TS中的错误。
从3.2开始,泛型的散布运算符的行为已更改。显然,道具的类型会被消除,这是负面的副作用,但是您可以通过在将{... props as P}散布到包装的组件中时将其投射回P来解决此问题。
因此,请尝试以下操作:
<Component
{...props as P}
asyncRequestHandler={asyncRequestHandler}
/>