-
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 support of fromEntries #26149
add support of fromEntries #26149
Conversation
src/lib/esnext.object.d.ts
Outdated
* Returns an object from an array of properties key/values | ||
* @param entries Array that contains the properties key and value. | ||
*/ | ||
fromEntries(entries: ArrayLike<[string, any]> | Iterable<[string, any]>): { }; |
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.
either Record<string, any>
or object
. {}
is the wrong type here.
src/lib/esnext.object.d.ts
Outdated
* Returns an object from an array of properties key/values | ||
* @param entries Array that contains the properties key and value. | ||
*/ | ||
fromEntries<T>(entries: ArrayLike<[string, T]> | Iterable<[string, T]>): { [ s: string]: 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.
consider using Record<string, T>
instead.
@@ -0,0 +1,13 @@ | |||
interface ObjectConstructor { |
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.
@RyanCavanaugh the new file will need to be added to the setup of the VS SDK. you will need to run VS\scripts\distributeLibFiles.bat
to update the setup.
* Returns an object from an array of properties key/values | ||
* @param entries Array that contains the properties key and value. | ||
*/ | ||
fromEntries<T>(entries: ArrayLike<[string, T]> | Iterable<[string, T]>): Record<string, 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.
Would be nice to support tuple types but not sure the compiler is clever enough to deal with that without having to define 200 overloads
fromEntries<K1 extends string, V1>(entries: [[K1, V1]]): { [K1]: V1 }
fromEntries<K1 extends string, V1, K2 extends string, V2>(entries: [[K1, V1], [K2, V2]]): { [K1]: V1; [K2]: V2 }
// ...
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.
It was nice if typescript had any way to declare types mapping from tuple to object
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.
Is there a real use case for Object.fromEntries
with a fixed number of entries? Seems like almost always you can just use object literal syntax in a case like that.
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.
I have a use case for that :)
im doing a-lot of these manipulations.
and if i had a generic way to express it, that would be awesome
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.
@Bnaya can you share a realistic code snippet where object literal syntax doesn't work but fixed-length fromEntries
does?
I want to call out a usability issue I've seen when working with this API: tuple types aren't inferred from array literals in typical situations for the "object comprehension" use case. For example, this snippet doesn't typecheck: const thingsById = Object.fromEntries(things.map((thing) => [thing.id, thing])); The underlying error is As one workaround, I can make my own function function entry<T>(key: string, value: T): [string, T] { return [key, value]; }
const thingsById = Object.fromEntries(things.map((thing) => entry(thing.id, thing))); but certainly that's not ideal since it's not in the JS standard library. Maybe the typechecker could be smarter here and either try both variants (array and tuple) or see from context that we prefer a tuple return type from the arrow function rather than an array type? |
This can already be encountered today when mapping data for passing to a Tangentially related, I encounter this more commonly now in my codebase when writing custom React hooks. As a really simple custom hook, take: function useLoggedState<T>(initialValue: T | (() => T) {
const [value, setValue] = React.useState(initialValue)
useEffect(() => {
console.log('value is', value)
}, [value])
return [value, setValue]
} Letting typescript infer the return type produces I've been fixing it with |
It would be great if When enum Values {
a = 'a',
b = 'b',
c = 'c',
}
const foo: { [key in Values]: number } = { a: 1, b: 2, c: 3 };
const bar = Object.fromEntries(Object.entries(foo)); |
* Returns an object from an array of properties key/values | ||
* @param entries Array that contains the properties key and value. | ||
*/ | ||
fromEntries(entries: ArrayLike<[string, any]> | Iterable<[string, any]>): Record<string, any>; |
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.
fromEntries
only accepts iterable object so probably we should remove ArrayLike
here. The Firefox implementation also throws for array-like object.
(Edit: Or replace it with ReadonlyArray
if we want it to be ES5 compatible.)
@Kingwl Object.fromEntries just hit stage 4 as (yet incomplete) ES2019 standard. Would you fix this PR to use |
@saschanaz sure, after a few moments later |
* Returns an object from an array of properties key/values | ||
* @param entries Array that contains the properties key and value. | ||
*/ | ||
fromEntries<T>(entries: ArrayLike<[string, T]> | Iterable<[string, T]>): Record<string, 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.
Drive-by comment: fromEntries
allows Symbol keys, not just strings.
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.
😸
The more comprehensive version is:
- The first argument must be an
Iterable
. The algorithm literally calls@@iterator
. Can't get away withArrayLike
s here. - The iterable must yield an object of the shape
{ 0?: string | number | symbol | null | { valueOf(): string | number } | { toString(): string }; 1?: any }
. This is probably not very useful for the actual type definition, and is incomplete as thevalueOf
may just be any other coercible value; but the point is that theIterable
's value needs not be an array orArrayLike
.
2a) The"0"
key / first element of tuple just needs to be something that can be cast into an object key, and that includesundefined
.undefined
becomes"undefined"
andnull
becomes"null"
. Pretty much the only thing I found that "doesn't work" isObject.create(null)
.
2b) The"1"
key / second element of tuple is the value associated with the key.
2c) Any of those keys may be getters or just missing entirely. They may even be write-only setters. - Duplicates overwrite each other in iteration order. The last value wins.
Current TypeScript treats tuples as assignable to objects with numeric literal keys. Using <K extends keyof any, T>
as the generic argument and Iterable<{ 0: K, 1: T }>
should work for most cases; with maybe a few more overloads for index signatures and a catch-all for mixed tuples.
This proposal is now stage 4, in ES2019. Is there any possibility of making the types for this function take an iterable of |
It's possible to do something like |
It seems reasonable to me that the return type is no more precise than |
I think we'll pick this up at #30934. It would be great if people could write up concise example testcases they think should pass / should fail for the definition WIP |
Fixes #25999