是否有任何 TypeScript 解决方案可以帮助我拥有“无限”数量的泛型类型,当然不必键入所有这些类型?
示例如下:
type Args<T extends React.ComponentType<any>> = { component: T, presetProps: React.ComponentProps<T>};
function buildComponents<T extends React.ComponentType<any>>(...args: Args<T>[] ) : any
function componentJ({name, age}: {name: string, age: number}){
return <h1>123</h1>
}
function componentI({ age}: { age: number}){
return <h1>123</h1>
}
buildComponents({component:componentJ, presetProps:{name: "Jon", age: 12}},
{component: componentI, presetProps:{age: 44}})
使用这段代码,我在 {component: componentI, presetProps:{age: 44}}
上遇到错误,因为它缺少 name
,但我想要这个从 componentI
而不是从 componentJ
获取类型,情况就是这样。
最佳答案
你可能想制作你的 buildComponents
通用函数不在 union 中要传递给 Args
的类型, 但在 tuple这种类型的。编译器不希望从异构列表(其中元素可能属于不同类型)推断联合,因为这通常是错误的:
function foo<T>(...args: T[]) { }
foo(1, 2, "3", 4); // error!
// -----> ~~~ string is not a number
另一方面,元组类型旨在支持异构列表:
function bar<T extends any[]>(...args: T) {}
bar(1, 2, "3", 4); // okay
那么让我们用 buildComponents()
试试看:
declare function buildComponents<T extends React.ComponentType<any>[]>(
...args: { [I in keyof T]: Args<Extract<T[I], React.ComponentType<any>>> }
): any;
我在那里所做的是 map the tuple type T
到一个新的元组,以便每个元素 T[I]
变成 Args<T[I]>
. the Extract
utility type 有一个小问题解决编译器错误(参见 microsoft/TypeScript#27995 )。但它有效:
buildComponents(
{ component: componentJ, presetProps: { name: "Jon", age: 12 } },
{ component: componentI, presetProps: { age: 44 } }
); // okay
另一种方法是制作T
Prop 类型的元组而不是组件类型。它有点干净:
declare function buildComponents<P extends any[]>(
...args: { [I in keyof P]: { component: React.ComponentType<P[I]>, presetProps: P[I] } }
): any;
并且还在调用站点工作:
buildComponents(
{ component: componentJ, presetProps: { name: "Jon", age: 12 } },
{ component: componentI, presetProps: { age: 44 } }
); // okay
关于typescript - "Arbitrary"通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67361427/