TypeScript Version: 3.5.3
Search Terms:
record, inference, iteration
Code
type ABC = "A"|"B"|"C";
let v : Record<ABC,number> = {A: 0, B: 0, C: 0};
for (let k in v) {
console.log(v[k])
}
Expected behavior:
k
is inferred to be type of K
of Record<K,V>
Actual behavior:
k
is inferred to be type of string
Playground Link: https://www.typescriptlang.org/play/index.html#code/C4TwDgpgBAggQgYSgXigIhmgPmu20JoDcAsAFDkA2EwUAblAFxQBKEAxgPYBOAJgDzwEAGgB2AVwC2AIwjcAfCigBvGMwAMwqHA1aEGgL6kKZAGY8oACmq0A1lACWo+gEoV5KJ6hdRAZ07UAHSUnADmlnQA2rYAui7kBuTkQA
Related Issues:
See this comment as to why this is so.
TL;DR: Sometimes the object has more keys, this can make things blow up:
type ABC = "A"|"B"|"C";
let vMore = {A: 0, B: 0, C: 0, D: ""};
let v : Record<ABC,number> = vMore; // Valid, typeof vMore is a sub-type of typeof v
for (let k in v) {
v[k as keyof typeof v].toExponential()
// k as keyof typeof v simulates k being what you would have expected it to be
// The statement above blows up when we get to k = "D"
}
@dragomirtitian , hm , is there a way to iterate over only known keys of T when these are known at compile time like ? so that there is no need for unsafe cast
@RyanCavanaugh , I disagree it is just a question. IMHO it s a usability bug, current experience doesn't make sense overall even though individual pieces might have, how come it is not possible iterate over Record in the type safe way?
for (let k in v)
should iterate over known keys only, because v
is typed, it has nothing to do with Object.keys()
output, because Object
is indeed ontyped, but for ... in
iteration doesn't have to use Object.keys()
Currently there is mismatch, v
is treated as untyped in for loop header, but treated as typed inside for loop body. It should be both one way or another (preferably typed :) ), currently it is not symmetrical and confusing.
This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.
lame
for (let k in v) should iterate over known keys only
TS doesn't do anything with the JS output. This is JS behavior, and such is working as intended. Sorry you don't it, but it has nothing to do with TS.
Just in case, asked a very similar question on SO: https://stackoverflow.com/questions/61829651/how-can-i-iterate-over-record-keys-in-a-proper-type-safe-way
Most helpful comment
lame