microsoft / microsoft/TypeScript

Can we cut down on `Object.assign` overloads?

Offen
#28,323 5 Kommentare 5 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Needs Proposal Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

We 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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Das Issue nennt keine Dateien, Tests oder Einstiegspunkte. Beginne damit, die vorgeschlagene assign-Typisierung sowie die Union- und Spread-Array-Beispiele aus dem Issue zu reproduzieren, und verfolge dann die bestehende Modellierung von Object.assign im TypeScript-Typchecker und in den Deklarationen der Standardbibliothek. Erledigt ist die Aufgabe mit einem überprüften Ansatz, der diese Fälle ohne widersprüchliche Intersections behandelt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
20/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.