React+Typescript表单构造器如何从组件记录正确推断组件Props类型
问题原因
Typescript 无法自动关联联合类型的 type 字段和对应组件的 Props 类型:当 FormItemComponent 是 FC<TFormItemText> | FC<TFormItemSelect> 联合类型时,TS 会要求传入的 props 必须同时满足所有组件 Props 的要求,而两个表单组件的 Props 没有公共交集,自然推导为 never 类型,触发报错。
可行解决方案
方案1:类型断言兜底(适合业务稳定、迭代少的场景)
你已经在逻辑上保证了 type 字段和 props 是匹配的,直接用类型断言跳过 TS 的推导检查即可,最简单高效:
const FormItem: FC<TFormItemProps<TFormItem>> = (props) => { const FormItemComponent = formItemsMap[props.type as EFormType]; return <FormItemComponent {...props as any} />; };
不想用 any 也可以写成更严谨的版本:
const FormItem: FC<TFormItemProps<TFormItem>> = (props) => { const type = props.type as EFormType; const FormItemComponent = formItemsMap[type]; return <FormItemComponent {...(props as ComponentProps<typeof FormItemComponent>)} /> as React.ReactElement; };
方案2:泛型+类型映射(类型安全,适合长期维护的公共组件)
如果需要保留完整的类型检查能力,可以先定义枚举和Props的映射关系,再用泛型约束组件入参:
// 先定义枚举值和对应Props的映射 type FormTypePropMap = { [EFormType.Text]: TFormItemText, [EFormType.Select]: TFormItemSelect } // 定义泛型FormItem组件 const FormItem = <T extends EFormType>(props: { type: T } & FormTypePropMap[T]) => { const FormItemComponent = formItemsMap[props.type] as React.FC<FormTypePropMap[T]>; return <FormItemComponent {...props} />; };
这种写法 TS 可以完全推导出入参和组件的匹配关系,不会触发类型报错,同时保留了所有类型校验能力,遍历 config 数组渲染时也能正常工作。
内容的提问来源于stack exchange,提问作者Roman Lisovsky
相关产品推荐
相关产品推荐

