嵌套对象类型的TypeScript键

嵌套对象类型的TypeScript键,typescript,Typescript,我想获得从配置对象推断出的此对象类型中on下所有键的并集: type Config = { initial: string; states: { idle: { on: { START: string; }; effect(): void; }; running: { on: { PAUSE: string; }; effect():

我想获得从配置对象推断出的此对象类型中
on
下所有键的并集:

type Config = {
initial: string;
states: {
    idle: {
        on: {
          START: string;
        };
        effect(): void;
    };
    running: {
        on: {
            PAUSE: string;
        };
        effect(): void;
    };
    paused: {
        initial: string;
        states: {
            frozen: {
                on: {
                    HEAT: string;
                };
            };
        };
        on: {
          RESET: string;
        };
    };
};
}

请注意,配置可以在
状态下嵌套
on
键。现在,我可以使用以下方法获取第一级关键点:

type KeysOfTransition<Obj> = Obj extends Record<PropertyKey, any> ? keyof Obj : never;
type TransitionKeys = KeysOfTransition<Config["states"][keyof Config["states"]]["on"]>
// "START" | "PAUSE" | "RESET"
type KeysOfTransition=Obj扩展记录?Obj的关键:从不;
类型转换键=转换键
//“开始”|“暂停”|“重置”

但是我不能在嵌套的联合体中获得
热量
。有什么想法吗?

可能有一些边缘情况,但这里有一个适用于您的示例的实现:

type KeysUnder<T, K extends PropertyKey> =
  T extends object ? {
    [P in keyof T]-?: (P extends K ? keyof T[P] : never) | KeysUnder<T[P], K>
  }[keyof T] : never;
    
type ConfigOnKeys = KeysUnder<Config, "on">;
// type ConfigOnKeys = "START" | "PAUSE" | "RESET" | "HEAT"
键入KeysUnder=
T扩展对象?{
[P in keyof T]-?:(P扩展K?keyof T[P]:从不)| KeysUnder
}[keyof T]:从不;
输入ConfigOnKeys=KeysUnder;
//键入ConfigOnKeys=“开始”|“暂停”|“重置”|“加热”
其思想是使用一个工具深入到对象属性中。要获取
下的
键,对于对象
T
,我们查看每个属性键
P
。如果
P
匹配
K
(在您的用例中,
上的
),那么您需要其属性值类型的键
T[P]
。递归位是,我们还将所有这些键连接到
下的


第二个lv
是否始终处于第二个lv
状态下
?这非常有效-我得到了一个“类型实例化太深,可能是无限的。”当将ConfigOnKeys提供给其他函数时,我可以找到它。是的,递归条件类型确实存在问题,可能的无限回归就是其中之一。有一些技术可以防止这种情况的发生,但是如果没有一个系统,就很难知道如何提供建议。