我想知道是否有更好的方法来获取对象的所有嵌套值类型。我的情况尤其可以概括为这种情况:
const myObj = {
group1: {
subGroup11: () => {return {} as const},
subgroup12: () => {return {} as const},
...
},
group2: {
subGroup21: () => {return {} as const},
subGroup22: () => {return {} as const},
...
}
...
}
所有最终值都是函数。
我目前正在做的事情是详尽无遗的,所以我从每个嵌套属性中获取所有类型:
type myType = <ReturnType
typeof myObj.group1.subGroup12 |
typeof myObj.group1.subGroup22 |
...
typeof myObj.group2.subGroup21 |
...
>
注意:
属性名称的索引符号只是为了示例。
组不一定具有相同的属性。
更新答案:
查看Maciej's和leonard's的答案,因为它们绝对正确。后一种方法检查的对象类型最多可达2个深度,而第一种方法则递归地应用于任何深度,还请注意,即使值不是函数,此最后一个解决方案也可以使用。谢谢Maciej,leonard和jcalz的贡献。
答案 0 :(得分:1)
您应该结合使用映射类型,推断和伪递归。沿T[K][keyof T[K]]
行的东西,不仅使用推论来获取R(返回类型),而且甚至查找级别1的属性是函数还是级别2(“组”对象),例如:
type FlattenTwoLevels<T extends {}> = {
[K in keyof T]: T[K] extends (...args: any) => any ? T[K] : T[K][keyof T[K]]
}[keyof T];
type ReturnMyObj = ReturnType<FlattenTwoLevels<typeof myObj>>;
我省略了(...args: any) => infer R
的推论,因为默认情况下ReturnType
在这里已经可以使用,因此FlattenTwoLevels
泛型助手仅需要{{1} }。
答案 1 :(得分:1)
我们可以创建一个通用类型,该通用类型适用于任何嵌套结构。在这里
type SelectFunctionRetunTypes<T extends object> =
{
[K in keyof T]
: T[K] extends (...args: any) => any
? ReturnType<T[K]>
: T[K] extends object
? SelectFunctionRetunTypes<T[K]>
: T[K] // primary value not a function and not an object
}[keyof T]
type ReturnsMyObj = SelectFunctionRetunTypes<typeof myObj>;
SelectFunctionRetunTypes是递归类型,当我们的值T[K]
是函数类型时,我们通过ReturnType
类型级别的函数从中获取返回类型,如果它不是函数,则检查其是否为对象,如果是,则通过递归调用SelectFunctionRetunTypes在此对象中继续相同的算法。最后一部分是当它不是函数而不是对象时,在这种情况下,我们只返回我们拥有的值的类型。
此泛型类型可用于所有类型的嵌套对象类型,如果值类型是函数,它将提供返回类型,否则将返回值类型。
中的完整示例