Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keyof object is number instead of string #41669

Closed
eek opened this issue Nov 24, 2020 · 6 comments
Closed

keyof object is number instead of string #41669

eek opened this issue Nov 24, 2020 · 6 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@eek
Copy link

eek commented Nov 24, 2020

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.

@MartinJohns
Copy link
Contributor

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

@ExE-Boss
Copy link
Contributor

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

@eek
Copy link
Author

eek commented Nov 24, 2020

Thanks for the link to #39543 @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.

@MartinJohns
Copy link
Contributor

MartinJohns commented Nov 24, 2020

@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.

@eek
Copy link
Author

eek commented Nov 24, 2020

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 ?

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Dec 1, 2020
@RyanCavanaugh
Copy link
Member

This is the intended behavior in all cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants