Reactjs 具有泛型初始类型的高阶组件
我有一个用于获取数据的通用联合类型,名为Reactjs 具有泛型初始类型的高阶组件,reactjs,typescript,higher-order-components,Reactjs,Typescript,Higher Order Components,我有一个用于获取数据的通用联合类型,名为RemoteData,我试图为其创建一个更高阶的组件: 导出接口IWithRemote{ 远程:远程数据; } 导出接口IWithData{ 资料:T; } 使用RemoteData导出函数(XComponent:React.ComponentType){ 返回类扩展了React.Component{ render(){ const{remote}=this.props; 开关(远程类型){ 案例RemoteDataKind.NotAsked: 还没问过你
RemoteData
,我试图为其创建一个更高阶的组件:
导出接口IWithRemote{
远程:远程数据;
}
导出接口IWithData{
资料:T;
}
使用RemoteData导出函数(XComponent:React.ComponentType){
返回类扩展了React.Component{
render(){
const{remote}=this.props;
开关(远程类型){
案例RemoteDataKind.NotAsked:
还没问过你;
案例RemoteDataKind。正在加载:
返回;
案例RemoteDataKind。成功:
返回
案例RemoteDataKind。失败:
返回daaaamn;
违约:
返回资产从不(远程);
}
}
};
}
但这些类型都不起作用。不确定我想做的事是否可能,不管怎样,我得到了
TS2322:类型“{data:T;}”不可分配给类型“K”
当我尝试将remote.data
分配给XComponent
的data
时
您可以找到重现问题所需的所有代码。有什么方法可以修复这些类型吗?您只需执行以下操作即可
export function withRemoteData<T>(
XComponent: React.ComponentType<IWithData<T>>
) {
return class extends React.Component<IWithRemote<T>> {
render() {
const { remote } = this.props;
switch (remote.kind) {
case RemoteDataKind.NotAsked:
return <div> nice not asked yet </div>;
case RemoteDataKind.Loading:
return <div> spinnnnnner </div>;
case RemoteDataKind.Success:
return <XComponent data={remote.data} />;
case RemoteDataKind.Failure:
return <div>daaaamn</div>;
default:
return assertNever(remote);
}
}
};
}
使用RemoteData导出函数(
XComponent:React.ComponentType
) {
返回类扩展了React.Component{
render(){
const{remote}=this.props;
开关(远程类型){
案例RemoteDataKind.NotAsked:
还没问过你;
案例RemoteDataKind。正在加载:
返回微调器;
案例RemoteDataKind。成功:
返回;
案例RemoteDataKind。失败:
返回daaaamn;
违约:
返回资产从不(远程);
}
}
};
}
HOC的参数类型,
XComponent
,期望其属性符合某些类型K
,除了数据之外,这些类型可能还包含一些额外的属性
但是HOC的props
类型IWithRemote
具有remote
属性,当kind
为Success
时,该属性被声明为只有数据
,没有其他内容
因此,当您使用
<XComponent data={remote.data} />
完整的类型是
type RemoteData<T, K extends IWithData<T>> =
| {
kind: RemoteDataKind.NotAsked;
}
| {
kind: RemoteDataKind.Loading;
}
| {
kind: RemoteDataKind.Success;
} & K
| {
kind: RemoteDataKind.Failure;
error: Error;
};
interface IWithRemote<T, K extends IWithData<T>> {
remote: RemoteData<T, K>;
}
interface IWithData<T> {
data: T;
}
export function withRemoteData<T, K extends IWithData<T>>(
XComponent: React.ComponentType<K>
) {
return class extends React.Component<IWithRemote<T, K>> {
但是这限制了可以传递给这个HOC的组件。如果我传递的任何组件包含多个道具数据
。它切断了其他道具。它有点起作用了。。。但它也将传递到HOC的组件的所有道具从道具传递到远程。您可以在这里看到:somethingElse
,在成功状态下成为remote
的一个属性,而不是一个道具。“它还将组件的所有道具从道具传递到远程”-我把它们放在那里,因为我不知道这些属性还能从哪里来。它们中有任何一个是非可选的吗?您是否需要了解HOC中这些属性的确切类型?如果这些问题的答案是“否”,我认为您甚至不需要K
generic type参数,您只需使用XComponent:React.ComponentType
type RemoteData<T, K extends IWithData<T>> =
| {
kind: RemoteDataKind.NotAsked;
}
| {
kind: RemoteDataKind.Loading;
}
| {
kind: RemoteDataKind.Success;
} & K
| {
kind: RemoteDataKind.Failure;
error: Error;
};
interface IWithRemote<T, K extends IWithData<T>> {
remote: RemoteData<T, K>;
}
interface IWithData<T> {
data: T;
}
export function withRemoteData<T, K extends IWithData<T>>(
XComponent: React.ComponentType<K>
) {
return class extends React.Component<IWithRemote<T, K>> {
case RemoteDataKind.Success:
return <XComponent {...remote} />;