You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Loading高阶组件(TypeScript)类型不兼容报错求助

解决TypeScript中Loading高阶组件的类型错误

你编写的Loading高阶组件代码如下:

function withLoading<T>(WrappedComponent: ComponentType<T>) {
  return function ({ isLoading, ...props }: { isLoading: boolean } & T) {
    return isLoading ? <p>Loading…</p> : <WrappedComponent {...props} />;
  };
}

TypeScript抛出的错误信息:

Type 'Omit<{ isLoading: boolean; } & T, "isLoading">' is not assignable to type 'IntrinsicAttributes & T'.
  Type 'Omit<{ isLoading: boolean; } & T, "isLoading">' is not assignable to type 'T'.
    'T' could be instantiated with an arbitrary type which could be unrelated to 'Omit<{ isLoading: boolean; } & T, "isLoading">'.(2322)

问题原因

TypeScript无法保证Omit<{ isLoading: boolean } & T, "isLoading">和泛型T的类型兼容性,核心问题有两点:

  • 泛型T可以是任意类型,如果T本身包含isLoading属性(比如定义为{ isLoading: string; name: string }),那么{ isLoading: boolean } & T会让isLoading的类型变成never(boolean和string的交叉类型无有效取值)。
  • 此时Omit后得到的类型是Omit<T, 'isLoading'>,和原T的结构完全不一致,自然无法赋值给T类型的组件props。

解决方案

方案1:约束T不包含isLoading属性(推荐)

通过泛型约束从根源避免类型冲突,确保T中不会出现isLoading属性:

import { ComponentType } from 'react';

function withLoading<T extends { isLoading?: never }>(WrappedComponent: ComponentType<T>) {
  return function ({ isLoading, ...props }: { isLoading: boolean } & T) {
    return isLoading ? <p>Loading…</p> : <WrappedComponent {...props} />;
  };
}

这里T extends { isLoading?: never }强制T要么没有isLoading属性,要么其类型为never(即无法赋值),确保Omit后的props完全匹配T的类型。

方案2:显式类型断言(适合允许T包含isLoading的场景)

如果确实需要T包含isLoading属性,可以用类型断言告知TypeScriptprops符合T的类型,但要注意逻辑上确保T的isLoading不是必填属性:

import { ComponentType } from 'react';

function withLoading<T>(WrappedComponent: ComponentType<T>) {
  return function (props: T & { isLoading: boolean }) {
    const { isLoading, ...rest } = props;
    return isLoading ? <p>Loading…</p> : <WrappedComponent {...rest as T} />;
  };
}

内容的提问来源于stack exchange,提问作者Géry Ogam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:17:48