TypeScript中如何从兄弟属性推断类型(异构数组场景)
TypeScript中实现异构Control数组的兄弟属性类型关联
问题场景
在TypeScript中需要实现:从对象的兄弟属性Component推断props的类型,且要支持异构数组(数组内每个元素的Component对应不同组件类型)。
原Control类型定义无法实现类型关联:
type Control = { Component?: React.Component props: Props<React.Component> }
单个元素的泛型方案可行,但直接用于数组会丢失具体类型约束:
type Control<T> = { Component?: T props: Props<T> } // 无法约束每个元素的props与对应Component匹配 type FormControls = Control[] const controls: FormControls = [ { Component: Input, props: {} }, { Component: Date, props: {} } ]
元组方案灵活性不足,需要动态的解决方案。
解决方案:泛型辅助函数实现动态类型推断
通过泛型函数让TypeScript自动推断数组中每个元素的类型关联,既保证灵活性又满足类型约束:
1. 定义通用泛型Control类型
使用React内置工具类型覆盖类组件和函数组件:
import type { ComponentType, ComponentProps } from 'react'; type Control<T extends ComponentType<any>> = { Component?: T; props: ComponentProps<T>; };
2. 实现泛型辅助函数
通过映射类型为数组每个位置生成对应类型约束:
function createControls<T extends ComponentType<any>[]>( controls: { [K in keyof T]: Control<T[K]> } ) { return controls; }
3. 实际使用
直接传入数组,TypeScript会自动校验每个元素的props与Component匹配:
const controls = createControls([ { Component: Input, props: { value: "hello", onChange: (e) => console.log(e.target.value) } // 必须符合Input的props类型 }, { Component: DatePicker, props: { selected: new Date(), onSelect: (date) => console.log(date) } // 必须符合DatePicker的props类型 } ]);
原理说明
- 泛型参数
T捕获数组中所有组件类型的集合,映射类型{ [K in keyof T]: Control<T[K]> }为每个数组索引位置生成对应的Control类型,确保Component和props一一关联。 - 无需手动指定泛型参数,TypeScript自动完成推断,保持数组的动态扩展性。
内容的提问来源于stack exchange,提问作者Muhammad Kashif Nazar
相关产品推荐
相关产品推荐

