Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 具有泛型初始类型的高阶组件_Reactjs_Typescript_Higher Order Components - Fatal编程技术网

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} />;