是否有一种方法来使用泛型类型一个复杂的对象数组,准确地比较一个React组件和它的道具类型?



我的团队已经为我们正在使用的API创建了typescript类型定义,所以我们不能碰源代码,只能碰定义。

我们有一个称为add的函数,它本质上是向主程序添加一个或多个反应组件。对象的props属性应取决于component属性上列出的组件类型。

它看起来像这样:

add(arg1, arg2, {
//some other args
children: [{
id: string1,
//BackButton can be a functional or class-based component
component: BackButton,
//BackButtonProps will be defined within BackButton
props: BackButtonProps
},
{
id: string2,
//SkipButton can be a functional or class-based component
component: SkipButton,
//SkipButtonProps will be defined within SkipButton
props: SkipButtonProps
}
]
});

作为参考,有一个函数的替代(重载)版本,它只添加一个组件而不是多个组件,我已经能够找出它的typescript。它看起来像这样:

add<T>(
id: string,
component: ComponentType<T>,
props: T
): void;

我的问题是这样的——因为子组件的数量是未知的,我怎么能在add函数上使用通用的,以便所有的子组件都是正确的类型(propscomponent属性匹配)?

add的通用签名是这样的:

declare function add<T extends any[]>(arg1: any, arg2: any, arg3: {
children: [...{ [K in keyof T]: {
id: string,
component: T[K]
props: React.ComponentProps<T[K]>     
}}]
}): void

泛型T将存储一个元组,其中每个元素都是一个react组件。对于传入数组中索引为K的每个元素,component类型将用作T[K]中的类型,props类型必须为React.ComponentProps<T[K]>

让我们看看实际操作:

const BackButton = (props: {a: string}) => {
return <div></div>
}
const SkipButton = (props: {b: string}) => {
return <div></div>
}
add(0, 0, {
children: [
{
id: "1",
component: BackButton,
props: { a: "123" }
},
{
id: "2",
component: SkipButton,
props: { b: "123" }
},
{
id: "3",
component: SkipButton,
props: { a: "123" } // Error: Type '{ a: string; }' is not assignable to type '{ b: string; }'
}
]
})

游乐场

相关内容