reactjs - Typescript:联合类型组件道具的 HOC 道具类型
问题描述
我有类似道具的组件:
setSelectedValue: (value: number | string) => void;
我想做 HOC,它有 setSelectedValue 道具,只能传递数字,也可以作为道具传递给原始组件,我看到它的类型如下:
setSelectedValue: (value: number) => void;
当我尝试做到这一点时,我收到 TS 错误消息:
Type '(value: number) => void' is not assignable to type '(value: number | string) => void'.
我怎样才能得到想要的结果?
解决方案
假设您的组件(comp.tsx):
import React from 'react';
import hocComp from './hocComp';
interface Props {
setSelectedValue: (value: number | string) => void; // number | string
}
class Comp extends React.Component<Props> {
render() {
return <div>Comp</div>;
}
}
export default hocComp<Props>(Comp); // LINE 1
和 HOC ( hocComp.tsx ):
import React from 'react';
interface Props {
setSelectedValue: (value: number) => void; // number // LINE 2
}
export default function hocComp<P extends object>(
WrappedComponent: React.ComponentType<P>
) {
return class extends React.Component<Props> { // LINE 3
render() {
return <WrappedComponent {...this.props as P} />; // LINE 4
}
};
}
以上面显示的方式定义,您可以在没有任何TypeError的情况下使用它(在 App.tsx 中) :
import React from 'react';
import Comp from './comp';
export default function App() {
function setSelectedValue(value: number) {
console.debug(value);
}
return (
<div className="App">
<h1>Hello World</h1>
<Comp setSelectedValue={setSelectedValue} />
</div>
);
}
这是CodeSandbox。
这是一个解释:
在调用 HOC时,我们将组件及其Props接口传递给 HOC。
export default withComp<Props>(Comp); // LINE 1
HOC 的定义:我们将传递的接口接收到一个泛型变量
P
中,并且传递的组件WrappedComponent
将其类型声明为React ComponentType,其中 P 作为 props 接口export default function withComp<P extends object>( WrappedComponent: React.ComponentType<P> ) {
最后,在 HOC 的内部渲染:我们调用传递的组件WrappedComponent并将所有具有在 HOC 本身(第 2 行)中定义的接口的道具传递给它 - (请注意,这些道具在 HOC 返回的类中使用 - 第 3 行)
return <WrappedComponent {...(this.props as P)} />; // LINE 4
现在你可以看到,
P has -> setSelectedValue: (value: number | string) => void
它Props has -> setSelectedValue: (value: number) => void
应该抛出TypeError,我们通过类型转换避免了它作为第 4 行。你可以尝试删除这个类型转换,它会开始显示错误。
您还可以查看这篇文章以了解TypeScript 中的泛型。
推荐阅读
- javascript - 从复选框获取百分比
- python - 如何实现纯 Python Pillow 图像插件?
- python - PyOpenGL - 如何加载在 mtl 文件中定义了颜色的 obj 文件
- numpy - 用对应于另一个数组的索引替换值
- java - SpringBoot - RequestMapping 将路径作为变量?
- teradata - 是否可以在 teradata 中进行多个活动计数检查?
- javascript - 我无法在 ios14.2 Safari 中播放带有静音属性的 html 音频
- c# - .Net 核心服务调用抛出 SocketException:试图以访问权限禁止的方式访问套接字
- c - 在 CLion 上找不到带有 MS-MPI 的 MPI(缺少:MPI_C_FOUND MPI_CXX_FOUND)
- javascript - 如何创建具有多个输入框的两列表