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.
Duplicate of #39543. Used search terms: keyof index number
Arguably, now聽that we聽have https://github.com/microsoft/TypeScript/pull/40336 and聽https://github.com/microsoft/TypeScript/pull/40598, keyof聽should聽report `${number}` for聽numeric index聽signatures.
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

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

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

How can then one keyof report only string and one report string | number ?
This is the intended behavior in all cases.
Most helpful comment
But both the variants report the exact same type for
GenericObject:How can then one
keyofreport onlystringand one reportstring | number?