Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typing keys of 2nd depth interface objects

Tags:

typescript

on a 3rd party library (which i can't change) i have the following interface:

interface MyInterface {
    x: {
        a: 1,
        b: 2,
        c: 3,
    },
    y: {
        d: 4,
        e: 5,
        f: 6,
    },
    z: {
        g: 7,
        h: 8,
        i: 9,
    },
}

i want to create a type (Values2ndDepth) that describes a union of all the keys of all the object in the interface, so the following will be enforced:

let key: Values2ndDepth<MyInterface>;
key = 'a'; // ok
key = 'i'; // ok
key = 'j'; // error - as doesn't exist in the above.

some of my tries:

type Values2ndDepth<T extends object> = keyof T[keyof T];
type Values2ndDepth<T extends object> = T extends {[k: string]: (infer R)} ? keyof R : never;
type Values2ndDepth<T extends object> = T extends Record<string, infer R> ? keyof R : never;
type Values2ndDepth<T extends object, K extends keyof T = keyof T> = T[K] extends object ? keyof T[K] : never;
like image 637
baryo Avatar asked Feb 21 '26 22:02

baryo


1 Answers

after a while - i found a solution!

type Values2ndDepth<T extends object, K extends keyof T = keyof T> =
    K extends keyof T ? T[K] extends object ? keyof T[K] : never : never;
  • making sure K describes T's keys
  • making sure the value of T[K] is another object
  • taking T[K]'s keys

any other solutions? maybe something more elegant?

like image 103
baryo Avatar answered Feb 27 '26 10:02

baryo