Skip to content

Object.keys should return keyof T #32321

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

Closed
fregante opened this issue Jul 10, 2019 · 6 comments
Closed

Object.keys should return keyof T #32321

fregante opened this issue Jul 10, 2019 · 6 comments

Comments

@fregante
Copy link

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>;

Playground Link: https://www.typescriptlang.org/play/#src=const%20feature%20%3D%20%7B%0D%0A%09description%3A%20''%2C%0D%0A%09screenshot%3A%20''%2C%0D%0A%09disabled%3A%20''%0D%0A%7D%3B%0D%0A%0D%0Aconst%20keys%20%3D%20Object.keys(feature)%3B

@j-oliveras
Copy link
Contributor

j-oliveras commented Jul 10, 2019

Already rejected multiple times, search for Object.keys

More info: https://stackoverflow.com/questions/55012174/why-doesnt-object-keys-return-a-keyof-type-in-typescript?r=SearchResults

@AnyhowStep
Copy link
Contributor

AnyhowStep commented Jul 10, 2019

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 T does not contain keys from types in the parent and ancestor [[prototype]]
  • T does not have optional properties
  • T is 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

@MartinJohns
Copy link
Contributor

Duplicate and rejected multiple times: #12253 (comment), #30314, #13254. #30228, #28899, #28284, #26901, #30749, #31087.

more info

@RyanCavanaugh
Copy link
Member

Maybe we should make a template just for this. It'd save people a lot of time.

@MartinJohns
Copy link
Contributor

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

@fregante
Copy link
Author

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()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants