keyof
keyof typeof
keyof should be a valid shorthand for keyof typeof. We describe both objects and types as having "keys" yet these are technically two different things. It is therefore unclear that keyof cannot be used on a plain javascript object, especially as typescript _is_ capable of inferring the keys of the object through the typeof operator. I think it would be helpful and less confusing if keyof was essentially equivalent to keyof typeof when used on a javascript object.
Reducing confusion and ambiguity around what a "key" is.
const t = {
a: 'foo',
}
type T = keyof t;
My suggestion meets these guidelines:
Already possible, you just need the typeof type operator to get the type of the value:
const t = {
a: 'foo',
}
type T = keyof typeof t;
This will cause problems if there are name collisions between values and types scopes
type obj = {a: number;};
const obj = {b: 'str'};
type T = keyof obj // a or b?
Even more problematic with classes
class Cls {
static stat = 123;
constructor() { }
log() {
console.log('logging')
}
}
type T = keyof Cls; // log or stat?
We generally don't ever make this kind of guesswork because it ends up creating more confusion than it's worth.
@dragomirtitian my issue specifically states this would be shorthand for that syntax
@IllusionMH that's no more ambiguous than:
class Cls {
static stat = 123;
constructor() { }
log() {
console.log('logging')
}
}
type T = keyof typeof Cls; // log or stat?
which is the equivalent of what I'm proposing
@RyanCavanaugh Maybe I didn't communicate this property, it wouldn't be guesswork, it would just be shorthand, to try and make more of an equivalence between "keys" in javascript and "keys" in typescript.
Unfortunately it seems that the name collision scuppers this specific proposal but I still think there is room for improvement here.
TL;DR: It's impossible to make keyof shorthand without breaking change and avoid collisions(=guesswork).
that's no more ambiguous than ...
keyof typeof Cls
Confusing at first and requires knowledge of TS behavior (know that there is 2 scopes: types and values, that keyof works on types scopes and typesof works on values scope, class declarations creates records in both and it's instance type which will be in type scope) - YES!
Ambiguous in terms where keys come from (types or values scope) - NO!
keyof typeof Cls explicitly states that keys should be taken from constructor function type (typeof Cls) and not an instance.
It's impossible to make keyof Cls to use Cls from values scope because it will break all existing code. So it's impossible to use shorthand for classes without breaking change and needs special handling in code and new rule of thumbs for users.
For case with object literal - it would look great at first, however keys will be wrong as soon as there will be name collision between scopes.
So either keyof should always work with values scope or it will be guesswork from users and problems if there are name collision.
IMO it is clear to me that the keyof a class would be the static members, classes themselves are not instantiated objects. But i agree it would be a breaking change because of collisions of scope, so that's fine.
Most helpful comment
This will cause problems if there are name collisions between values and types scopes
Even more problematic with classes