Description
Bug Report
Types with an index signature for strings have number
included in keyof
, that is that keyof { [x: string]: unknown } = string | number
. I find this unexpected. A possible explanation for this behaviour is that number
can index such types be being implicitly coerced to a string:
const a: { [x: string]: unknown; } = {};
a[0] = "example"; // this is fine
However, consider that Record<string, unknown>
is equally capable of such behaviour, and keyof Record<string, unknown>
does not include number
:
const b: Record<string, unknown> = {};
b[0] = "inconsistency"; // this is also fine
In that case, does it make sense for number
to appear, considering it is not a prerequisite for numbers to implicitly index string-indexed types? Or alternatively, does Record<string, unknown>
incorrectly not report number
?
More examples are provided in the playground link.
🔎 Search Terms
- keyof string index signature
- keyof index signature
- index signature
- string index signature includes number
🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about ctrl-f "keyof"
⏯ Playground Link
Playground link with relevant code
💻 Code
This is a short snippet of the playground example with the main inconsistent example.
type A = { [x: string]: unknown; }
type KA = keyof A;
// ^? - type KA = string | number
const a: A = {};
a[0]; // indexable by number therefore number in keyof A?
type B = Record<string, unknown>
type KB = keyof B;
// ^? - type KB = string
const b: B = {};
b[0]; // indexable by number without number in keyof B
🙁 Actual behavior
keyof { [x: string]: unknown }
unexpectedly includes number
, whereas keyof Record<string, unknown>
does not, which is inconsistent.
🙂 Expected behavior
keyof { [x: string]: unknown }
should not include number
.
I find this more reasonable than the alternative possibly expected behaviour: keyof Record<string, unknown>
and all types which number
can index via being implicitly coerced to a string should include number
as a key.