Closed as not planned
Closed as not planned
Description
🔎 Search Terms
- "for-in" loop keyof type assertion
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about
Object.keys
(https://stackoverflow.com/questions/55012174/why-doesnt-object-keys-return-a-keyof-type-in-typescript)
⏯ Playground Link
💻 Code
interface ABC {
a: number;
b: number;
c: number;
}
function foo(abc: ABC) {
let k: keyof ABC;
for (k in abc) {
console.log(abc[k].toFixed());
}
}
const abcd = {a: 1, b: 2, c: 3, d: new Date()};
foo(abcd); // 💥 abc[k].toFixed is not a function
🙁 Actual behavior
TypeScript allows this code without a type assertion on k
.
🙂 Expected behavior
TypeScript should require a type assertion on k
, whose type really should be string
. Something like:
for (const kStr in abc) {
const k = kStr as keyof ABC;
}
The code it allows is equivalent to a type assertion but does not use the word "as".
Additional information about the issue
This has been the behavior of TS forever, but I had trouble finding an issue requesting that TS be more strict about this, rather than less.
If you want to shoot yourself in the foot, you should at least have to write a type assertion somewhere.
Incidentally, the error you get if you write let k: "a" | "b"
is a bit misleading given the behavior:
function foo(abc: ABC) {
let k: "a" | "b";
for (k in abc) {
// ~ The left-hand side of a 'for...in' statement must be of type 'string' or 'any'. (2405)
console.log(abc[k].toFixed());
}
}
string
would be sound, but evidently TS only requires something that keyof ABC
is assignable to, not string
.