TypeScript provides no way to express this at the time foo is declared because somebody might later add additional properties to foo
, for instance by:
let o: any;
o = foo;
o.x = 'hello';
Then, Object.keys(foo)
will also return x
, but trying to increment 'hello'
is probably not what you intend ...
More generally, in typescript, an object may always contain surplus properties, because this is what allows you to do:
interface Person = {
name: string;
}
interface Student extends Person {
university: string;
}
let student: Student = ...;
let person: Person = student;
That is, TypeScript can never be sure that an Object has no surplus properties, and that's why Object.keys
returns Array<string>
rather than Array<keyof typeof foo>
.
In your case, I might do:
const fooKeys = Object.keys(foo) as Array<keyof typeof foo>;
right after declaring foo. That way, we take a snapshot of the keys we intend to iterate over before anybody else has a chance to modify them. Then, you can do:
fooKeys.forEach(key => {
foo[key]++;
});