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

ReactJS TypeScript中如何为动态组件传递联合类型的动态Props?

问题描述

我有一个Next.js首页,通过getServerSideProps接收数组格式的homeData作为props,同时定义了组件映射对象pages,根据Redux中的currentStep(0-6的数字)渲染对应组件,并传递homeData[currentStep]作为组件的data属性。

各组件都有自己的Props类型定义,比如Welcome组件的Props:

type WelcomeProps = {
  data: {
    title: string
    subtitle: string
    sim_image: string
    packages: string[]
  }
  handleStepClick: (direction: 'next' | 'prev') => void
}

当前问题是:在VS Code中hover查看data props时,它的类型显示为各组件Props中data类型的交集,但我期望它是联合类型(即WelcomeProps['data'] | SimTypeProps['data'] | ...)。

解决方案

核心问题是TypeScript无法自动关联currentStep、pages中的组件以及homeData的索引对应关系,导致类型推断错误。可以通过以下步骤修复:

1. 定义步骤与Data类型的映射

先为每个步骤对应的data类型创建一个映射类型,明确步骤编号和对应数据结构的关系:

// 先导入或定义各组件的Props类型
import type { WelcomeProps } from './Welcome';
import type { SimTypeProps } from './SimType';
import type { NumberSearchProps } from './NumberSearch';
// ... 其他组件的Props类型

// 建立步骤编号与对应data类型的映射
type StepDataMap = {
  0: WelcomeProps['data'];
  1: SimTypeProps['data'];
  2: NumberSearchProps['data'];
  3: ShoppingCartProps['data'];
  4: PersonalInformationProps['data'];
  5: ShippingAddressProps['data'];
  6: OrderConfirmationProps['data'];
};

2. 为homeData指定正确类型

将首页接收的homeData类型从any改为StepDataMap(数组索引与步骤编号对应,符合TypeScript的索引类型推断):

export default function Home({ homeData }: { homeData: StepDataMap }) {
  // ... 后续代码
}

3. 约束组件映射对象的类型

给pages对象指定类型,让它的键对应步骤编号,值是接收对应data类型的组件,确保组件与数据类型的匹配:

const pages: { 
  [K in keyof StepDataMap]: React.ComponentType<{ 
    data: StepDataMap[K];
    handleStepClick?: (direction: 'next' | 'prev') => void;
  }> 
} = {
  0: Welcome,
  1: SimType,
  2: NumberSearch,
  3: ShoppingCart,
  4: PersonalInformation,
  5: ShippingAddress,
  6: OrderConfirmation,
};

4. 约束currentStep的类型

确保currentStep的类型是keyof StepDataMap(即0|1|2|3|4|5|6),而不是宽泛的number。如果Redux的selectStep返回的是number,可以通过类型断言缩小范围:

const currentStep = useSelector(selectStep) as keyof StepDataMap;

最终效果

完成上述修改后,当hover查看data={homeData[currentStep]}时,TypeScript会正确推断出它的类型是StepDataMap[keyof StepDataMap],也就是所有步骤对应data类型的联合类型,而非交集。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:03:12