Search code examples
typescripttypeofkeyof

Typescript "keyof typeof myObj" gives me the actual keys on "myObj", but not if it has a type "myObj: myType". How can i do both?


I want to get the actual keys of "myObj", but also ensure its type. If I add a type I no longer get the actual keys. How can i do both?

example 1

const myObj = {
    in01: 'Hello', 
    in02: 'World'
}
type actualKeys = keyof typeof myObj // result: "in01" | "in02" (this is what I want)

example 2

type myType = {
    [x: string]: string
}
const myObj: myType = { // I get to validate the type (what I want)
    in01: 'Hello', 
    in02: 'World'
}
type actualKeys = keyof typeof myObj // result: string | number (this is no longer the actual keys. Not what I want)

Solution

  • Your Indexable type myType allows number as keys.

    Therefore keyof myType returns string | number

    Since you define myObj to be of type myType, keyof typeof myObj is the same as keyof myType, hence the string | number.

    With TS 4.9 (yet to be released), you will be able to ensure the type without actually typing it using the satisfies keyword.

    type myType = {
        [x: string]: string
    }
    const myObj = {  // ok
        in01: 'Hello', 
        in02: 'World'
    } satisfies myType
    
    const myObj2 = {  // KO
        in01: 'Hello', 
        in02: 'World'
        0: 'lala', // nope
    } satisfies myType
    
    
    type actualKeys = keyof typeof myObj
    

    Playground