Ped*_*edo 3 typescript typescript-generics react-typescript
是否有任何 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}})
Run Code Online (Sandbox Code Playgroud)
使用此代码,我在 上出错{component: componentI, presetProps:{age: 44}},因为它错过了name,但我希望它从 中获取类型,componentI而不是从 中获取类型componentJ,就是这种情况。
您可能希望使您的buildComponents函数通用,而不是在要传递给的类型的联合中Args,而是在此类类型的元组中。编译器不希望从异构列表(其中元素可能具有不同类型)推断联合,因为这通常是一个错误:
function foo<T>(...args: T[]) { }
foo(1, 2, "3", 4); // error!
// -----> ~~~ string is not a number
Run Code Online (Sandbox Code Playgroud)
另一方面,元组类型旨在支持异构列表:
function bar<T extends any[]>(...args: T) {}
bar(1, 2, "3", 4); // okay
Run Code Online (Sandbox Code Playgroud)
所以让我们尝试一下buildComponents():
declare function buildComponents<T extends React.ComponentType<any>[]>(
...args: { [I in keyof T]: Args<Extract<T[I], React.ComponentType<any>>> }
): any;
Run Code Online (Sandbox Code Playgroud)
我在那里所做的是将元组类型映射 T到一个新元组,以便每个元素都T[I]变成Args<T[I]>. 有一个繁琐位的Extract实用型工作围绕编译器错误(见微软/打字稿#27995)。但它有效:
buildComponents(
{ component: componentJ, presetProps: { name: "Jon", age: 12 } },
{ component: componentI, presetProps: { age: 44 } }
); // okay
Run Code Online (Sandbox Code Playgroud)
另一种方法是创建Tprops 类型而不是组件类型的元组。它更干净一点:
declare function buildComponents<P extends any[]>(
...args: { [I in keyof P]: { component: React.ComponentType<P[I]>, presetProps: P[I] } }
): any;
Run Code Online (Sandbox Code Playgroud)
并在呼叫站点也工作:
buildComponents(
{ component: componentJ, presetProps: { name: "Jon", age: 12 } },
{ component: componentI, presetProps: { age: 44 } }
); // okay
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
69 次 |
| 最近记录: |