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。


这里有一个解释:

  1. 在调用HOC时,我们将组件及其道具接口传递到HOC中

    export default withComp<Props>(Comp); // LINE 1

  2. HOC的定义:我们接收到传递到泛型变量P的接口,传递的组件WrappedComponent将其类型声明为React ComponentType,p作为道具接口

    export default function withComp<P extends object>( WrappedComponent: React.ComponentType<P> ) {

  3. 最后,在HOC的内部渲染:我们调用传递的组件,WrappedComponent,并向它传递所有的props(接口定义为HOC本身(行2(-(注意,这些props在HOC-行3返回的类中使用(

    return <WrappedComponent {...(this.props as P)} />; // LINE 4

  4. 现在您可以看到P has -> setSelectedValue: (value: number | string) => voidProps has -> setSelectedValue: (value: number) => void,它们应该抛出为TypeError,我们通过Type Casting作为LINE4避免了这一点。您可以尝试删除此类型转换,它将开始显示错误。

您也可以查看这篇文章来了解TypeScript中的泛型

最新更新