我有一个类似道具的组件:
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时,我们将组件及其道具接口传递到HOC中
export default withComp<Props>(Comp); // LINE 1
HOC的定义:我们接收到传递到泛型变量
P
的接口,传递的组件WrappedComponent
将其类型声明为React ComponentType,p作为道具接口export default function withComp<P extends object>( WrappedComponent: React.ComponentType<P> ) {
最后,在HOC的内部渲染:我们调用传递的组件,WrappedComponent,并向它传递所有的props(接口定义为HOC本身(行2(-(注意,这些props在HOC-行3返回的类中使用(
return <WrappedComponent {...(this.props as P)} />; // LINE 4
现在您可以看到、
P has -> setSelectedValue: (value: number | string) => void
和Props has -> setSelectedValue: (value: number) => void
,它们应该抛出为TypeError,我们通过Type Casting作为LINE4避免了这一点。您可以尝试删除此类型转换,它将开始显示错误。
您也可以查看这篇文章来了解TypeScript中的泛型。