Typescript: keyof returns (string聽| number)[] instead of string[]

Created on 3 Jan 2019  路  4Comments  路  Source: microsoft/TypeScript


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

Docs help wanted

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:

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.

All 4 comments

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!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

siddjain picture siddjain  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments

wmaurer picture wmaurer  路  3Comments

jbondc picture jbondc  路  3Comments