Skip to content

keyof object is number instead of string  #41669

Closed

Description

TypeScript Version: 4.1.2 (actually all versions 3.3.3 - 4.1.2)

Search Terms:
keyof declared object is not only string, keyof object type, keyof declared key, keyof

Code

type GenericObject = { [key: string]: any };
type GenericKeyType = keyof GenericObject;

Expected behavior:
GenericKeyType should be of type string

Actual behavior:
GenericKeyType is number | string

Playground Link:
https://www.typescriptlang.org/play?#code/C4TwDgpgBA4hB2EBOBLAxgeQEYCsJuCgF4oBvKAbQGsIQAuKAZ2FXgHMBdBgQ3hCgC+AbgBQI0JFgJk6ANK0AKuGgkaIAPYAzKYlSZc+YEKA

Related Issues:
Didn't find anything.

Activity

  1. MartinJohns commented on Nov 24, 2020

    @MartinJohns
    Contributor

    Duplicate of #39543. Used search terms: keyof index number

  2. ExE-Boss commented on Nov 24, 2020

    @ExE-Boss
    Contributor

    Arguably, now that we have #40336 and #40598, keyof should report `${number}` for numeric index signatures.

  3. eek commented on Nov 24, 2020

    @eek
    Author

    Thanks for the link to #39543 Martin Johns (@MartinJohns), but I still think this is a bug.

    I'm saying it's a bug because I'm explicitly saying that GenericObject must have only string keys, and I've seen the reply saying it's by design decisions of keyof to be able to allow string | number | symbol from here.

    But I think explicit types should be respected. Not to mention there's also an inconsistency between:

    type GenericObject = { [key: string]: any };
    type GenericKeyType = keyof GenericObject; // number | string

    image

    and

    type GenericObject = { [key in string]: any };
    type GenericKeyType = keyof GenericObject; // string

    image
    Playground link here

    And I don't think there's any difference between:
    [key: string] and [key in string] // sure, the in is meant for other usages but should still be the same.

  4. MartinJohns commented on Nov 24, 2020

    @MartinJohns
    Contributor

    Radu-Sebastian Amarie (@eek) But it's not a bug, it's a design decision. One you probably disagree with, but nonetheless not a bug.

    Not to mention there's also an inconsistency between: [...]

    Different syntaxes are for different features. Consistency is not a desirable goal for something like this.

  5. eek commented on Nov 24, 2020

    @eek
    Author

    Different syntaxes are for different features. Consistency is not a desirable goal for something like this.

    But both the variants report the exact same type for GenericObject:

    image

    How can then one keyof report only string and one report string | number ?

  6. RyanCavanaugh commented on Dec 1, 2020

    @RyanCavanaugh
    Member

    This is the intended behavior in all cases.

  7. locked as resolved and limited conversation to collaborators on Oct 21, 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

    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