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

TypeScript React HOC报错:类型'P'不存在属性'item'

解决React高阶组件(HOC)中TypeScript类型报错:Property 'item' does not exist on type 'P'

问题原因

你的HOC泛型P未添加类型约束,TypeScript无法推断传入的props中包含item属性——虽然运行时props确实存在该属性,但编译阶段的类型检查会抛出错误。另外,当前HOC传递给被包裹组件的hasLoaded属性,并未在UserDetails的props接口中定义,这也会引发潜在的类型问题。

解决方案

  1. 给泛型P添加约束:让P继承包含item属性的类型,明确告知TypeScriptprops中存在该属性。
  2. 调整组件props接口:如果需要使用HOC传递的hasLoaded,就在IUserDetails中添加该属性;如果不需要,则移除HOC中传递hasLoaded的逻辑。

以下是修正后的代码示例:

方案1:保留hasLoaded传递(组件接收该属性)

// UserDetails.tsx
import { User } from '../../../services/userService';
import { WithGetter } from '../../HOCs/WithGetter';

interface IUserDetails {
  item: User;
  hasLoaded: boolean; // 添加HOC传递的属性
}

const UserDetails = ({ item, hasLoaded }: IUserDetails) => {
  return (
    <div id='user-details'>
      <h2>Display User - {item?.id}</h2>
      <h3>{item?.name}</h3>
      {!hasLoaded && <p>Loading...</p>} {/* 可选使用hasLoaded状态 */}
    </div>
  );
};

export default WithGetter(UserDetails);
// WithGetter.tsx
import { useState, useEffect } from 'react';
import { StandardLoader } from '../UtilityComponents/Loaders/Loaders';

export function WithGetter<P extends { item: unknown }>(
  WrappedComponent: React.ComponentType<P & { hasLoaded: boolean }>
) {
  const ComponentWithGetter = (props: P) => {
    const [hasLoaded, setHasLoaded] = useState<boolean>(false);
    useEffect(() => {
      setHasLoaded(true);
    }, []);

    return (
      <div className='border-2 p-4'>
        {JSON.stringify(props.item)} {/* TypeScript可识别item属性 */}
        {hasLoaded ? (
          <WrappedComponent {...props} hasLoaded={hasLoaded} />
        ) : (
          <StandardLoader />
        )}
      </div>
    );
  };
  return ComponentWithGetter;
}

方案2:不传递hasLoaded(仅HOC内部处理加载状态)

如果UserDetails不需要hasLoaded属性,修改HOC如下:

// WithGetter.tsx
import { useState, useEffect } from 'react';
import { StandardLoader } from '../UtilityComponents/Loaders/Loaders';

export function WithGetter<P extends { item: unknown }>(
  WrappedComponent: React.ComponentType<P>
) {
  const ComponentWithGetter = (props: P) => {
    const [hasLoaded, setHasLoaded] = useState<boolean>(false);
    useEffect(() => {
      setHasLoaded(true);
    }, []);

    return (
      <div className='border-2 p-4'>
        {JSON.stringify(props.item)}
        {hasLoaded ? (
          <WrappedComponent {...props} /> {/* 不再传递hasLoaded */}
        ) : (
          <StandardLoader />
        )}
      </div>
    );
  };
  return ComponentWithGetter;
}

关键说明

  • 泛型约束P extends { item: unknown }确保了所有传入该HOC的组件,其props都必须包含item属性,TypeScript因此可以安全访问props.item。
  • 若需要更精确的类型(比如item必须是User类型),可将约束改为P extends { item: User },但会降低HOC的通用性。

内容的提问来源于stack exchange,提问作者Brian Battenfeld

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 15:30:51