Skip to content

keyof { [x: string]: unknown } unexpectedly includes number #48269

Closed
@otonashixav

Description

@otonashixav

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions