You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
keyof any incorrectly maps (only) to type string #21983
As for making keyof return symbols.... Object.keys only returns string keys at runtime, and many other JS constructs only operate over string keys. I think we may do symbolof operator to maintain compatibility and keep a distinction between the two namespaces.
I don't mind having keyOf and symbolOf for backward compatibility but can we also have anyKeyOf which would return both type of keys because I can't think of a use case where I would want to use symbolOf on its own.
Having keyof only refer to string keys can be useful, introducing symbolof seems to be the right way to go. My guess is most of the time people are going to need keyof more than symbolof anyway. If someone consistently needs both they can just create a type alias type SymbolKeyOf<T> = keyof T | symbolof T.
Symbols are usually used to store hidden values on an object, and are used far less than string keys.
keyof as is can be useful when using Object.keys or Object.entries which do not return symbols as keys.
keyof has already been declared as string keys, and is being used as such, why break it? It also makes sense seeing as Object.keys refers only to strings.
Can you provide a use case where you would need to use keyof T | symbolof T many times throughout? Is there a instance where an alias wouldn't be enough?
ogwh that could be fixed either way: either by (a) adding symbols to keyof, or by (b) adding symbolof and redefining Readonly<T> to use keyof T | symbolof T.
So yes, that is a problem with the current definitions, but its not necessary an argument for one approach over the other.
Currently works perfectly, but if symbols were included you'd get the resulting type error
Type '(string | number)[]' is not assignable to type 'number[]'.
When in reality that would not be the correct type to return.
In response to some of your summary:
I think I've shown an example that proves this is not something based merely on wording. For a long time there were no symbols in JS, hence why when talking about objects, a key generally refers to a string property (even if technically the spec defines it as either string or symbol).
(+ 7, 8) I'm afraid I don't get what your point is here. Though you are correct that Object.keys does not directly correlate to keyof, in most cases though usage of keyof as the return type of Object.keys does work (and is useful).
My example above shows your proposal would be a breaking change.
symbolof would not break anything, and allow us to do everything we would need to
One last note about expanding keyof
If one were to try and separate keys into 2 types of symbol and string:
interface O {
a; b; c;
[sA]; [sB];
}
type OStringKeys = keyof O & string;
type OSymbolKeys = keyof O & symbol;
it would result in this mess:
type OStringKeys = ("a" & string) | ("b" & string) | ("c" & string) | (unique symbol & string) | (unique symbol & string)
type OSymbolKeys = ("a" & symbol) | ("b" & symbol) | ("c" & symbol) | (unique symbol & symbol) | (unique symbol & symbol)
if we left keyof alone and added symbolof, we'd get:
type OStringKeys = keyof O = "a" | "b" | "c"
type OSymbolKeys = symbolof O = unique symbol | unique symbol
ogwh it is producing an error because you've enabled strict function types, and is due to the fact that Object.keys does not return the type (keyof T)[], there was a proposal to have it do so, but that wouldn't be correct in all scenarios (discussion on that). Here's a updated version with strict function types enabled (Also tested locally with 2.7.2)
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
Activity
yortus commentedon Feb 16, 2018
If
symbolof(#20721) was supported, you could write it like this:Jessidhia commentedon Feb 16, 2018
(There are no
numberproperty keys. All non-symbol property keys are either strings or numeric strings.)Jessidhia commentedon Feb 16, 2018
I just think it's not appropriate as a widened type for the result of
keyof.yortus commentedon Feb 16, 2018
ogwh that was in Wesley Wigham (@weswigham)'s comment for why
keyofshould be just strings.As for
keyof any, since this is not referring to the keys of any particular object, why not just use thePropertyKeytype in your annotation instead?dinoboff commentedon Feb 16, 2018
I don't mind having
keyOfandsymbolOffor backward compatibility but can we also haveanyKeyOfwhich would return both type of keys because I can't think of a use case where I would want to usesymbolOfon its own.robbiespeed commentedon Feb 16, 2018
Having
keyofonly refer to string keys can be useful, introducingsymbolofseems to be the right way to go. My guess is most of the time people are going to needkeyofmore thansymbolofanyway. If someone consistently needs both they can just create a type aliastype SymbolKeyOf<T> = keyof T | symbolof T.robbiespeed commentedon Feb 18, 2018
keyofas is can be useful when usingObject.keysorObject.entrieswhich do not return symbols as keys.keyofhas already been declared as string keys, and is being used as such, why break it? It also makes sense seeing asObject.keysrefers only to strings.Can you provide a use case where you would need to use
keyof T | symbolof Tmany times throughout? Is there a instance where an alias wouldn't be enough?1 remaining item
yortus commentedon Feb 20, 2018
ogwh that could be fixed either way: either by (a) adding symbols to
keyof, or by (b) addingsymbolofand redefiningReadonly<T>to usekeyof T | symbolof T.So yes, that is a problem with the current definitions, but its not necessary an argument for one approach over the other.
robbiespeed commentedon Feb 20, 2018
ogwh Here's a simple example of how expanding
keyofto include symbols could break existing codeCurrently works perfectly, but if symbols were included you'd get the resulting type error
When in reality that would not be the correct type to return.
In response to some of your summary:
Object.keysdoes not directly correlate tokeyof, in most cases though usage ofkeyofas the return type ofObject.keysdoes work (and is useful).symbolofwould not break anything, and allow us to do everything we would need toOne last note about expanding
keyofIf one were to try and separate keys into 2 types of symbol and string:
it would result in this mess:
if we left
keyofalone and addedsymbolof, we'd get:robbiespeed commentedon Feb 20, 2018
ogwh it is producing an error because you've enabled strict function types, and is due to the fact that
Object.keysdoes not return the type(keyof T)[], there was a proposal to have it do so, but that wouldn't be correct in all scenarios (discussion on that).Here's a updated version with strict function types enabled (Also tested locally with 2.7.2)
typescript-bot commentedon Mar 7, 2018
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.