1

I am trying to create a generic type that when parametrized with some object type, will form a new type allowing only any path that is present in the object type. I have adapted my solution from here: How to match nested Keys in Typescript

While this solution works for objects, it does not behave properly for tuples, when the tuple is not top-level. Why is this?

I believe the answer may lie in my lack of understanding of mapped types and typescript types, specifically with regard to the behavior of indexing and keyof. The only place I have been able to find documentation of the combination of these two things together is here in the docs (cmd+f "[keyof").

I have seen a similar answer that would mostly accomplish my goal, but at this point I'm in a bit of a bloodlust and just want to understand why my current solution is failing. That other answer is a whole other can of worms: I have found that if you change ...keys to keys, it stops working, which confuses me even further. - These seems to be due to type inference.

// Note: using 4.1.3

// Expect this to take an object and produce as a type the paths that are accessible in the object

type Path<V> = {
  [K in keyof V]:
    Path<V[K]> extends any[]
      ? [K, ...Path<V[K]>]
      : never
    | [K]
    | []
}[keyof V]

// Example objects

type InputArrayType = [
  string,
  string,
  string
]

type InputNestedDictType = {
  a: {
    aa: string
  },
  b: {
    ba: string
  }
}

type InputNestedArrayType = [
  [
    string,
    string
  ],
  [
    string,
    string
  ], {
    a: string
  }
]

// Expectations that are working properly:

const path0: Path<InputArrayType> = ["0"]; // okay
const path1: Path<InputArrayType> = ["3"]; // expected type error
const path2: Path<InputNestedDictType> = ["a"] // okay
const path3: Path<InputNestedDictType> = ["a","aa"] // okay
const path4: Path<InputNestedDictType> = ["a","ba"] // expected type error
const path5: Path<InputNestedDictType> = ["z"] // expected type error
const path6: Path<InputNestedArrayType> = ["0"] // okay
const path7: Path<InputNestedArrayType> = ["2","a"] // okay

// Expectations that are not working properly:

const path8: Path<InputNestedArrayType> = ["0","0"] // Unexpected type error
user1982116
  • 141
  • 6

0 Answers0