reactjs - 使用 TypeScript 严格类型化消费属性的 React 高阶组件
我正在尝试编写一些比仅仅注入属性更复杂的高阶 React 组件。这些 HOC 必须能够:
- 接收未被(或仅可选择性地)转发给包装组件的属性
- 为封装的组件提供一些新属性
- 在创建它们时接受额外的参数
据我所知,这意味着我们必须有三种类型:
- HOC 提供给被包装组件的属性
- HOC 使用的属性,但被包裹的组件不一定关心这些属性
- HOC 不关心的被包装组件的属性
我有以下代码可以正常工作,但我找不到在将 props 传递给封装组件时避免 any 类型转换的方法:
import React, { ComponentType } from 'react';
// Props of the wrapped component without the props provided by the HOC
type StrictWrappedProps<WrappedProps, InjectedProps> = Omit<
WrappedProps,
keyof InjectedProps
>;
type WrappedComponent<WrappedProps, InjectedProps> = ComponentType<
WrappedProps & InjectedProps
>;
type HOCType<WrappedProps, InjectedProps, OwnProps> = ComponentType<
OwnProps & StrictWrappedProps<WrappedProps, InjectedProps>
>;
type LengthifyOwnProps = {
name: string;
};
type LengthifyInjectedProps = {
length: number;
};
export const lengthify = <WrappedProps extends {}>(
Wrapped: WrappedComponent<WrappedProps, LengthifyInjectedProps>,
multiplier: number
): HOCType<WrappedProps, LengthifyInjectedProps, LengthifyOwnProps> => ({
name,
...props
}) => {
const length = name.length * multiplier;
return <Wrapped {...props as any} length={length} />;
};
这里是该高阶组件的一个使用示例:
const myComp = ({ bool, length }: { bool: boolean; length: number }) => (
<p>
Bool is: {bool}. Length is: {length}
</p>
);
const EnhancedMyComp = lengthify(myComp, 2);
const usage = () => <EnhancedMyComp bool={true} name="Hello" />;
any 类型转换是一个小的变通办法,但我想找到更严格的类型定义方法。
React TypeScript 关于 HOCs 的速查表链接到了 TypeScript 仓库中的这个 bug,但它似乎或多或少已经解决,并且只与注入属性的 HOC 有关。StackOverflow 上的其他问题也似乎是关于注入属性,或者对 ComponentType 类型的困惑。