d-_-b
d-_-b

Reputation: 23201

How to have typescript check for valid object property names

I'm using typescript and have an object defined with different people's names:

const data = {
   John: someTypedVariable,
   Alex: someTypedVariable,
   Anna: someTypedVariable,
   ... hundreds more added over time
}

If I were to try and access data.missingValue it would correctly fail to compile.

If I try to iterate the object:

for(const key in data){
   const item = data[key]; // error
}

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ John: ....

I can change data to:

const data: Record<string, someTypedVariable> = {
    ...
}

but then I'd lose the typings which would allow errors like data.missingValue.

So is there a way to guarantee a valid property without explicitly defining a list of keys, like:

type keys = "John" | "Alex" | "Anna" | ...hundreds more

Upvotes: 1

Views: 635

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371049

If you need to iterate over the object's keys with for..in, assert that the key is a property of the object after defining it:

for (const key in data) {
    const typedKey = key as keyof typeof data;
    const item = data[typedKey];
}

(or inline it, if you don't use typedKey again)

Another option, to retrieve both the key and value at once, is to use Object.entries:

Object.entries(data).forEach(([key, item]) => {
  // ..
});

Upvotes: 4

Related Questions