'How can I get Typescript to understand what the value type of a homogenous object is without losing keys from static declaration?

How can I get Typescript to understand what the value type of an object is without losing access to the key information from its static declaration?

In the below code I want the benefit of

  • TS knowing the type of the value, in this case a function so I don't have to specify it's signature every time.
  • TS knowing the keys of the object from static declaration so I can reference them in a type safe fashion from elsewhere

This object is homogenous and will have lots of functions, specifying the signature every time seems like a pain.

Example 1 - TS doesn't know the keys of the object

    interface Foo {
        [key: string]: (n: number) => any
    }
    
    const obj1: Foo = {
        // TS already knows that `n` is a number 🙂
        bar(n) {return n}
    }
    
    type KeyOfObj1 = keyof typeof obj1
    const kob1: KeyOfObj1 = "xyz" // This does not fail static type checking 😢
    

Example 2 - TS doesn't know the signature of the functions which are the object's values

    const obj2 = {
        // Notice here I have to specify the type of `n` 😢
        bar(n: number) {return n}
    }
    
    type KeyOfObj2 = keyof typeof obj2
    const kob2: KeyOfObj2 = "xyz" // This fails static type checking 🙂

How can I get the best of both worlds?

p.s. I understand I could pull out the keys into an enum but that seems rather ugly and repetitive, though perhaps it really is the only way 😕



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source