TypeScript类型定义:props类型与component参数类型一致(无固定值列表)
如何在TypeScript中确保对象的props类型与component参数类型一致(未知所有可能取值的情况)
要解决这个问题,核心是让TypeScript自动为每个children元素推断匹配的props和component参数类型,无需预先枚举所有可能的类型。可以通过**类型推断(infer)**定义约束类型,强制每个子元素的props类型严格对应其component的入参类型。
基础解决方案
通过infer提取组件函数的参数类型,绑定到props上:
// 定义约束类型:props必须与component的参数类型完全匹配 type ValidChild = { component: (props: infer T) => null; props: T; }; // 重新定义One接口,children为ValidChild数组 interface One { children: ValidChild[]; } // 示例组件 const ComponentOne = (props: string) => null; const ComponentTwo = (props: number) => null; // 合法示例:props与component参数类型匹配 const validOne: One = { children: [ { props: 'hello world', component: ComponentOne }, { props: 123, component: ComponentTwo } ] }; // 非法示例会被TypeScript自动报错:props类型与component参数不匹配 const invalidOne: One = { children: [ { props: 5, // 类型不匹配ComponentOne的string参数,触发错误 component: ComponentOne } ] };
原理
ValidChild类型利用infer T自动解析component函数的参数类型T,并要求props的类型必须等于T。- 当
One接口的children被定义为ValidChild[]时,TypeScript会逐个校验数组元素,确保每个元素的props和component参数类型严格一致。 - 该方案无需预先知晓所有组件类型,完全由TypeScript自动推断约束。
进阶方案(保留精确类型)
如果需要保留每个子元素的具体类型信息(而非统一为ValidChild),可以使用泛型函数创建实例:
type ValidChild<T> = { props: T; component: (props: T) => null; }; // 泛型函数确保传入的children数组中每个元素都符合ValidChild约束 function createOne<T extends ValidChild<any>[]>(children: [...T]) { return { children }; } // 自动推断每个子元素的具体类型 const one = createOne([ { props: 'hello', component: ComponentOne }, { props: 123, component: ComponentTwo } ]); // 此时 one.children[0].props 类型为 string,one.children[1].props 类型为 number
这种方式既保证了类型匹配,又保留了每个子元素的精确类型,便于后续代码中使用具体类型。
内容的提问来源于stack exchange,提问作者EzioMercer
相关产品推荐
相关产品推荐

