TypeScript中如何通过Props数组动态生成React组件?
问题根源
你遇到的类型报错是因为 TypeScript 无法感知数组遍历过程中 input 字段和 props 类型的绑定关系:默认情况下你定义的 fields 数组中,input 是独立的联合类型('text' | 'select'),props 也是独立的联合类型(TextProps | ElementProps),TS 不知道这两个值是一一对应的,因此会把所有可能的 props 类型混在一起做校验,才会出现 onBlur 类型不兼容的报错。
解决方案
无需类型断言,只需要调整类型定义和渲染逻辑的写法,让 TS 可以识别到 input 和 props 的绑定关系即可:
- 首先给组件映射对象加
as const固化类型,保证 TypeScript 可以拿到精确的键值和对应组件类型,同时修正属性名大小写不一致的问题:
const INPUTS = { text: { component: TextInput, controlled: false }, select: { component: Select, controlled: true } } as const; type InputMap = typeof INPUTS;
- 重新定义
FieldConfig为分布式联合类型,让每个联合成员的input和props自动绑定:
import { ComponentProps } from "react"; export type FieldConfig = { [K in keyof InputMap]: { input: K; props?: ComponentProps<InputMap[K]["component"]>; } }[keyof InputMap];
这时候 FieldConfig 会自动生成如下的联合类型,每个成员的 input 和 props 是一一对应的:
// 自动生成的联合类型等价于: type FieldConfig = | { input: 'text', props?: TextProps } | { input: 'select', props?: ElementProps }
- 把渲染单条字段的逻辑抽为独立函数,TypeScript 会自动对单个联合类型做收窄:
function renderField(field: FieldConfig) { const { component: Component } = INPUTS[field.input]; return <Component {...field.props} />; } // 遍历数组时直接调用即可 <div> {fields.map((field) => renderField(field))} </div>
这样调整之后,TypeScript 可以正确识别每个 field 对应的组件和 props 类型,不会再抛出类型不兼容的错误。
内容的提问来源于stack exchange,提问作者MoSheikh
相关产品推荐
相关产品推荐

