Search code examples
typescript

Can I use arg1 of function to narrow the type of arg2 in the same function?


Here is the example of what I want to do:

const obj = {
  parent1: {
    child1: "child-key1",
    child2: "child-key2",
  },
  parent2: {
    child3: "child-key3",
    child4: "child-key4",
  }
} as const

const func = (
  parentKeyName : keyof typeof obj,
  childKeyName: keyof typeof obj[parentKeyName]
) => {}

// When I fill first arg, I want code completion to suggest me the list of keys for second arg
func("parent2", "child3") 

But the definition of 'func' above gives me an error: enter image description here

Is there any way to use first arg to narrow the type of second arg?


Solution

  • Using TypeScript Generics:

    const obj = {
        parent1: {
            child1: "child-key1",
            child2: "child-key2",
        },
        parent2: {
            child3: "child-key3",
            child4: "child-key4",
        }
    } as const
    
    const func = <
        T extends keyof typeof obj,
        K extends keyof typeof obj[T]
    >(
        parentKeyName: T,
        childKeyName: K
    ) => { }
    
    func("parent1", "child1") // ok
    func("parent1", "child2") // ok 
    func("parent2", "child3") // ok 
    func("parent2", "child4") // ok 
    func("parent1", "child3") // wrong 
    func("parent1", "child4") // wrong 
    func("parent2", "child1") // wrong 
    func("parent2", "child2") // wrong