-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Add stricter parameter types for Object.values and Object.entries #20553
Conversation
@andy-ms We could just define values as |
@weswigham the problem there is the unsoundness because of structural non-sealed types const a = { a: 'a string', b: 123 }
const b: Pick<typeof a, 'a'> = a
const values = Object.values(b) // string[]; but actually has a number inside too EDIT: my example actually turns out to already be incorrect today, because of the overload that tries to handle dictionary types. |
@weswigham What would you think of that signature with |
@Kovensky any time you alias a type you lose information w.r.t. the index operator. But the thing is, I'm pretty sure that definition (at least for |
src/lib/es2017.object.d.ts
Outdated
@@ -3,25 +3,14 @@ interface ObjectConstructor { | |||
* Returns an array of values of the enumerable properties of an object | |||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. | |||
*/ | |||
values<T>(o: { [s: string]: T } | { [n: number]: T }): T[]; | |||
values<T extends object>(o: T): T[keyof T][]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do not use keyof
here. same reasoning as #13989 (comment)
src/lib/es2017.object.d.ts
Outdated
|
||
/** | ||
* Returns an array of key/values of the enumerable properties of an object | ||
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. | ||
*/ | ||
entries(o: any): [string, any][]; | ||
entries<T extends object>(o: T): [string, T[keyof T]][]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
@mhegazy @weswigham The original goal was to not accept |
that would work. |
Waiting for #21075, then will merge from master |
Thanks. Really loving the TypeScript project and how quickly and thoroughly you fix any reported bugs. |
Fixes #20550
Added
| string | number | boolean | symbol
to avoid falling into the second overload unnecessarily;Object.values
on a primitive returns[]
of these so it's effectively anever[]
in that case (though we infer{}[]
).I'm also not too happy about returning
any
from builtin functions.--noImplicitAny
won't help you there. The only case I found where the first overload won't match any more isObject.values(() => {})
, in which case a return of{}[]
is probably better since a function's unlikely to have the properties you intend to get.