Skip to content

Tooltip for mapped type displays number key instead of string #47214

Closed

Description

@ASDFGerte

Bug Report

Unlikely this hasn't been already mentioned before, but i couldn't find anything.

A mapped type using string keys which represent numbers displays these as numbers in the tooltip.

type A = { [K in '0']: number }; // { 0: number }
type B = { '0': number };        // { '0': number }
type C = { 0: number };          // { 0: number }
type Atest = '0' extends keyof A ? 'yes' : 'no'; // 'yes'

🔎 Search Terms

mapped type tooltip displays number string key

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about #common-bugs-that-arent-bugs

⏯ Playground Link

Playground link with relevant code

🙁 Actual behavior

Tooltip displays

type A = {
    0: number;
}

🙂 Expected behavior

Tooltip displays

type A = {
    '0': number;
}

PS: I'd prefer it even more, if TS stopped allowing keys being some subtype of number altogether, but i guess that's a different topic.

Activity

  1. MartinJohns commented on Dec 21, 2021

    @MartinJohns
    Contributor

    I would expect { '0': number } to show { 0: number }. But in the end these two types are absolutely the same.

  2. ASDFGerte commented on Dec 21, 2021

    @ASDFGerte
    Author

    As javascript object initializers, they are identical. Typescript types, for what i'd assume are legacy reasons, differentiate between the two:

    type X = { '0': number };
    type Y = { 0: number };
    type Xtest1 = '0' extends keyof X ? 'yes' : 'no'; // 'yes'
    type Xtest2 = 0   extends keyof X ? 'yes' : 'no'; // 'no'
    type Ytest1 = '0' extends keyof Y ? 'yes' : 'no'; // 'no'
    type Ytest2 = 0   extends keyof Y ? 'yes' : 'no'; // 'yes'
  3. MartinJohns commented on Dec 21, 2021

    @MartinJohns
    Contributor

    That's interesting. I wonder if that's intentional. The object types are identical.

    type T1 = [X] extends [Y] ? 'yes' : 'no' // "yes"
    //   ^?
    
    type T2 = [Y] extends [X] ? 'yes' : 'no' // "yes"
    //   ^?
    

    (Note the // ^?, it will inline show the type above the caret. Neat little feature.)

  4. ASDFGerte commented on Dec 21, 2021

    @ASDFGerte
    Author

    The root issue is, that while javascript only has string and symbol properties, typescript allows properties to additionally have any subtype of number. It then does a lot of magic (like the types extending each other) to ignore this extra again, which unsurprisingly sometimes fails. This imho causes a lot of issues, and i'd think it wouldn't really be necessary anymore, now that template string types are powerful enough (would need some work, for e.g. declare const x: { [prop: `${number}`]: number }; x[0] = 0; not giving implicit any errors, while e.g. x['0'] = 0 works, but that doesn't look terribly difficult, compared to other things). That's only a guess though, without knowing the full picture.

    PS: The // ^? is nice, i'll try remember that for future snippets.

  5. RyanCavanaugh commented on Jan 4, 2022

    @RyanCavanaugh
    Member

    Type display generally tries to use the "original spelling" of the type whenever possible (example: B), literally just pulling whatever text you have in the sourcefile into the display text. When a type is the computed result of an immediately-evaluable operation, as A is, then there is no "original spelling" and you get the normalized form. '0" isn't quoted here the same reason a property name that doesn't look like a number gets quoted.

  6. ASDFGerte commented on Jan 5, 2022

    @ASDFGerte
    Author

    Thanks, so i guess the tooltip just accidentally helped me differentiate between string and number keys sometimes. I had thought that was intended, to help notice what type a type's key was. Object property keys potentially being some subtype of number has thrown me off on multiple occasions. Guess I'll have to continue checking by writing a temporary conditional type, when i want to know. Although rare, it is relevant every now and then (e.g. tuples with their named string keys, narrowing variables to be a key of an exact type, ...).

    PS: Closing here soon, unless there are more thoughts or links related to the topic, or generally for how to deal with number being a subtype of PropertyKey.

  7. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct options

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions