Object.keys should return `keyof T`
fregante opened this issue Β· 6 comments
TypeScript Version: 3.6.0-dev.20190717
Code
const feature = {
description: '',
screenshot: '',
disabled: ''
};
const list = Object.keys(feature);Expected behavior:
keys<T extends object>(o: T): Array<keyof T>;typeof list = Array<"description" | "screenshot" | "disabled">Actual behavior:
keys(o: {}): string[];typeof list = string[]Workaround:
const feature = {
description: '',
screenshot: '',
disabled: ''
};
const list = Object.keys(feature) as Array<keyof typeof feature>;Already rejected multiple times, search for Object.keys
Object.keys() does not return (keyof T)[] in the general case.
In some specific instances, it will. In most others, it will not.
declare const x : { a : number };
Object.keys(x);You might expect the above to return ["a"] but it's possible for it to return ["a", "b"], too.
Because {a: number, b: number} is assignable to {a: number}
If anything, we can only say Object.keys() returns keyof T if,
- We have no number keys
- We have no symbol keys
keyof Tdoes not contain keys from types in the parent and ancestor[[prototype]]Tdoes not have optional propertiesTis some kind of "strict" object that does not allow extra properties (TS doesn't have such a concept at the moment)
I'm sure there are other constraints I haven't thought of.
[Edit]
Oh. The linked Stack Overflow answer explains it better
Maybe we should make a template just for this. It'd save people a lot of time.
@RyanCavanaugh I actually just copied my last comment and added the other issue. But this is a good candidate for the FAQ (but I doubt it's being checked before).
Itβs because it sounds so obvious that I just checked the open issues before opening this one π
Nobody expects keyof to be different from keys()