- Be aware that any objects your function receives as parameters might have additional keys.
- Use
Object.entries
to iterate over the keys and values of any object. - Use a ++for-in++ loop with an explicit type assertion to iterate objects when you know exactly what the keys will be.
- Consider
Map
as an alternative to objects since it's easier to iterate over.
//// Check that the "Surprisingly" aside continues to work: // verifier:reset // verifier:prepend-subset-of-id-to-following:abc:1-5 [source,ts]
function foo(abc: ABC) { let k: keyof ABC; for (k in abc) { // ^? let k: keyof ABC (equivalent to "a" | "b" | "c") const v = abc[k]; // ^? const v: string | number } }
////
const obj = {
one: 'uno',
two: 'dos',
three: 'tres',
};
for (const k in obj) {
const v = obj[k];
// ~~~~~~ Element implicitly has an 'any' type
// because type ... has no index signature
}
const obj = { one: 'uno', two: 'dos', three: 'tres' };
// ^? const obj: {
// one: string;
// two: string;
// three: string;
// }
for (const k in obj) {
// ^? const k: string
// ...
}
for (const kStr in obj) {
const k = kStr as keyof typeof obj;
// ^? const k: "one" | "two" | "three"
const v = obj[k]; // OK
}
interface ABC {
a: string;
b: string;
c: number;
}
function foo(abc: ABC) {
for (const k in abc) {
// ^? const k: string
const v = abc[k];
// ~~~~~~ Element implicitly has an 'any' type
// because type 'ABC' has no index signature
}
}
const x = {a: 'a', b: 'b', c: 2, d: new Date()};
foo(x); // OK
function foo(abc: ABC) {
for (const kStr in abc) {
let k = kStr as keyof ABC;
// ^? let k: keyof ABC (equivalent to "a" | "b" | "c")
const v = abc[k];
// ^? const v: string | number
}
}
function foo(abc: ABC) {
for (const [k, v] of Object.entries(abc)) {
// ^? const k: string
console.log(v);
// ^? const v: any
}
}
function foo(abc: ABC) {
const keys = ['a', 'b', 'c'] as const;
for (const k of keys) {
// ^? const k: "a" | "b" | "c"
const v = abc[k];
// ^? const v: string | number
}
}
const m = new Map([
// ^? const m: Map<string, string>
['one', 'uno'],
['two', 'dos'],
['three', 'tres'],
]);
for (const [k, v] of m.entries()) {
// ^? const k: string
console.log(v);
// ^? const v: string
}