0

I have a simple object type in TypeScript and an object made of all the keys in this object but not of the same type. I'm expected hasOwnProperty or hasOwn to narrow the type to the type keys but it isn't. Here is a small example that summarize the problem and what I expect to happen:

type Example = {
    foo: string;
    bar: string;
}

type ExampleKeys = keyof Example;

// the type is Readonly to make sure there are no more extra keys in here later
const translation: Readonly<{[key in ExampleKeys]: string}> = {
    foo: "oof",
    bar: "rab",
};

function test(example: Example) {
    for (const [key, _] of Object.entries(example)) {
        if (translation.hasOwnProperty(key)) {
            // I expect key to be of type ExampleKeys here
        }

        if (Object.hasOwn(translation, key)) {
            // Tried with the new hasOwn method but didn't work too
        }
    }
}

In general I want to iterate over the object and get only the relevant keys. I know that because of structural typing I might get additional properties and I try to stay away from them but I want to know how to do it without duplicating the keys list or making assertions. My translation object is needed and thanks to the type hinting I make sure that I wont make mistakes although I duplicate the keys there, so I guess using it is okay but there must be a more general way, I hope at least.

yotamN
  • 711
  • 2
  • 9
  • 22

1 Answers1

0

in my opinion , type guard function should be created to narrow the type of key

function isExampleKey(key: string): key is ExampleKeys {
    return key in translation;
}

Then use this function inside

function test(example: Example) {
    for (const [key, _] of Object.entries(example)) {
        if (isExampleKey(key)) {
            // key is now narrowed to the specific ExampleKeys type
        }
    }
}
oluroyleseyler
  • 802
  • 2
  • 5
  • It works but I'm trying to understand why TypeScript doesn't handle type narrowing with hasOwnProperty. Am I missing something? – yotamN Apr 28 '23 at 19:28
  • TypeScript infers the type of the key variable as string because that is the return type of the Object.entries() method. Therefore, you cannot narrow down the type of key to ExampleKeys just by using hasOwnProperty(). – oluroyleseyler Apr 28 '23 at 20:38