Can we cut down on `Object.assign` overloads?
See original GitHub issueWe can convert unions into intersections (thanks @jcalz!), and we can model variadic args pretty well, so I figured I’d try to model Object.assign
with a single overload. Here’s what I came up with:
// Maps elements of a tuple to contravariant inference sites.
type MapContravariant<T> = {
[K in keyof T]: (x: T[K]) => void
}
type TupletoIntersection<T, Temp = MapContravariant<T>> =
// Ensure we can index with a number.
Temp extends Record<number, unknown>
// Infer from every element now.
? Temp[number] extends (x: infer U) => unknown ? U : never
: never;
declare function assign<T extends object, Rest extends object[]>(
x: T,
...xs: Rest
): T & TupletoIntersection<Rest>;
Unfortunately this doesn’t quite give the right results on the following:
let asdf = assign({x: "hello"}, Math.random() ? {x: "hello"} : {z: true });
Currently the type of asdf
is:
| ({ x: string; } & { x: string; z?: undefined; })
| ({ x: string; } & { z: boolean; x?: undefined; })
What a beautiful type! Unfortunately you can see that the second element of the union tries to intersect types with conflicting properties for x
which is nonsense.
Additionally, @weswigham pointed out that this really won’t work for the case where you started off with just a plain array whose elements are eventually spread into Object.assign
.
I do wonder if there’s anything better we can do here.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:5
- Comments:5 (1 by maintainers)
Top Results From Across the Web
c++ - dealing with assignment operator overloads; can you re ...
No, you cannot re-seat a reference. Consider: int a = 42, b = 43; int &ar = a; ar = b;. How can...
Read more >14.15 — Overloading the assignment operator - Learn C++
The assignment operator (operator=) is used to copy values from one object to another already existing object.
Read more >Object.assign() - JavaScript - MDN Web Docs
The Object.assign() static method copies all enumerable own properties from one or more source objects to a target object.
Read more >Overloading - C# in Depth
Overloading. Just as a reminder, overloading is what happens when you have two methods with the same name but different signatures.
Read more >Operator Overloading, C++ FAQ - Standard C++
Can I overload operator== so it lets me compare two char[] using a string comparison? ... For example, after an assignment, the two...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
After the culmination of several TS versions, I think I found a typing that leads to correct answers in the cases I can think of:
The type of
is correctly inferred to be
{ x: string, z?: undefined } | { x: string | undefined, z: boolean }
Playground link which also has type tests: https://tsplay.dev/4w1LyW
@DanielRosenwasser does this count for some definition of “better”?
Cool, thank you for the explanation! Yeah like I said I didn’t see your work on this until I found this issue myself, happy to see other people have been thinking more about it