1

Can I get an objects actual keys when I'm using an interface to describe the object?

Example below

interface IPerson {
    name: string;
}
interface IAddress {
    [key: string]: IPerson;
}

const personInAddressObj: IAddress= {
    someAddress1: {
        name: 'John',
    },
    someAddress2: {
        name: 'Jacob',
    }
} as const

type Keys = keyof typeof personInAddressObj;

Id want the type Keys to have the values "someAddress1 | someAddress2". If I take the interface out of "personInAddressObj", I can get the keys. However, when the interface is used, I can't get the actual keys out of the object.

5
  • If you mean using those keys as type (that what's you write), then you can't. Typescript compiles on static info, hence you can't have runtime data at compile-time. However, if the keys are used for runtime stuffs, you can leverage the Object.keys(personInAddressObj), which gets you the keys as array of strings. Have a look here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Dec 9, 2022 at 7:24
  • See here for the corresponding open TypeScript feature request. Commented Dec 9, 2022 at 7:39
  • @MarioVernari Objects declared with a const assertion (as const) are compile-time information. Commented Dec 9, 2022 at 7:41
  • "If I take the interface out of personInAddressObj, I can get the keys." - so, why not do that? There's no point in using as const if you did assign to a variable declared as IAddress. Commented Dec 9, 2022 at 7:45
  • @RobbyCornelissen that's new to me. Many thanks for pointing me out. Commented Dec 9, 2022 at 7:54

1 Answer 1

4

There's an open feature request for this specific use case.

For your specific example, I think you can use the new (since TypeScript 4.9) satisfies operator to have both a const assertion and type checking:

interface IPerson {
    name: string;
}

interface IAddress {
    [key: string]: IPerson;
}

const personInAddressObj = {
    someAddress1: {
        name: 'John'
    },
    someAddress2: {
        name: 'Jacob'
    }
} as const satisfies IAddress;

type Keys = keyof typeof personInAddressObj;
// ↑ inferred as "someAddress1" | "someAddress2"

Playground link

Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly what I wanted to achieve. Thanks for helping out!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.