1

Not sure if this is possible... but I am trying to convert an interface to tuples using the keys of the interface.

Interface:

interface User {
  _id: string;
  first_name: string;
  last_name: string;
  address: {
    firstLine: string;
    secondLine: string;
    state: string;
    zip: string;
    details: {
      active: boolean;
      primary: boolean;
    }
  }
}

The new type should allow me to create an array as such:

const args: UserKeysTuple = ["_id", ["address", ["zip", "details": ["active"]]];

Order does not matter.

Nick McLean
  • 601
  • 1
  • 9
  • 23
  • Is any key allowed at any place or is there some kind of hierarchy logic? – Tobias S. May 08 '22 at 19:15
  • Tuples are ordered, properties are not ordered. So this doesn't really make much sense. See: https://stackoverflow.com/questions/55127004/how-to-transform-union-type-to-tuple-type sepcifically _"You can't rely on the ordering of a union type. It's an implementation detail of the compiler; since `X | Y` is equivalent to `Y | X`, the compiler feels free to change one to the other."_ (This is about unions but relevant because you would have to get the keys from that type, which would be a union) – Alex Wayne May 08 '22 at 19:15
  • The syntax of the `args` example is not valid, you cannot have `:` in an array like that. Did you mean `["_id", ["address", ["zip", ["details", ["active"]]]]` – H.B. May 08 '22 at 19:19
  • @H.B. - Yes! You are right, comma, not colon. – Nick McLean May 08 '22 at 19:29

1 Answers1

0

This is possible to some degree using mapped types:

type KeyTuple<T> = {
  [Key in keyof T]:
    T[Key] extends object ?
      T[Key] extends Date ?
        Key :
        NestedTuple<T, Key> :
      Key
}[keyof T][]
type NestedTuple<T, K extends keyof T> = [K, KeyTuple<T[K]>];

type UserKeysTuple = KeyTuple<User>;

This has some limitations though, among them:

  • It's a mess; see also the special case for Date because it is an object but usually is treated like a primitive
  • This does not check for duplicates, so a key could be listed multiple times without error

Playground

H.B.
  • 166,899
  • 29
  • 327
  • 400