TypeScript Version: 3.3.0-dev.20190103
Search Terms:
keyof index types
The issue
In the documentation we have the following explained:
Index types and string index signatures
keyof and T[K] interact with string index signatures. If you have a type with a string index signature, keyof T will just be string[...]:
interface Map<T> {
[key: string]: T;
}
let keys: keyof Map<number>; // string
Doc link: https://www.typescriptlang.org/docs/handbook/advanced-types.html
However, with TypeScript 3.2, keys is actually of type (string | number)[].
(I also tried with 3.3.0-dev.20190103, it gives the same results).
Expected behavior:
I would expect keys to be of type string[], since the Map interface defines the properties to be of type string.
Is the documentation wrong, or is there an issue in TypeScript?
Playground Link:
http://www.typescriptlang.org/play/#src=interface%20TestMap%3CT%3E%20%7B%0D%0A%20%20%20%20%5Bkey%3A%20string%5D%3A%20T%3B%0D%0A%7D%0D%0Alet%20keys%3A%20keyof%20TestMap%3Cnumber%3E%3B%20%2F%2F%20string%0D%0A
Documentation is out of date - we made a change a few months ago here. Here's the documentation repo for anyone who can get to it before me https://github.com/Microsoft/TypeScript-Handbook/
@DanielRosenwasser Done! Addressed in https://github.com/Microsoft/TypeScript-Handbook/pull/941
I'm not sure if this is a docs issue or a TS issue, but it's definitely still an issue. The Advanced Types docs currently have this in their example code for index types:
interface Dictionary<T> {
[key: string]: T;
}
let keys: keyof Dictionary<number>; // string
However, the type of keys is actually string | number, and I can call keys = 42; just fine. The docs even explicitly state If you have a type with a string index signature, keyof T will just be string which is just wrong.
The docs have been updated, and will get shipped with the next site deploy - thanks everyone!
Most helpful comment
I'm not sure if this is a docs issue or a TS issue, but it's definitely still an issue. The Advanced Types docs currently have this in their example code for index types:
However, the type of
keysis actuallystring | number, and I can callkeys = 42;just fine. The docs even explicitly stateIf you have a type with a string index signature, keyof T will just be stringwhich is just wrong.