microsoft / microsoft/TypeScript

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

Ouverte
#28,323 5 commentaires 5 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Needs Proposal Suggestion
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

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.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

L’issue ne mentionne aucun fichier, test ou point d’entrée. Commencez par reproduire le typage assign proposé ainsi que les exemples d’unions et de tableaux avec spread de l’issue, puis suivez la modélisation existante de Object.assign dans le vérificateur de types de TypeScript et les déclarations de la bibliothèque standard. Le travail est terminé lorsqu’une approche revue gère ces cas sans intersections en conflit.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Fonctionnalité
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
À clarifier
Accessibilité débutants
20/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.