microsoft / microsoft/TypeScript

Allow classes to implement unions of object types

Ouverte
#62,630 17 commentaires 4 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

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

Description

🔍 Search Terms

class extends union type

✅ Viability Checklist
⭐ Suggestion

Allow classes to extend unions of object types when the types in the union have the same set of properties.

The goal is to allow type-narrowing on class instances by checking a discriminant field.

📃 Motivating Example

I often have classes that represent data that can be in one of several states, and whose fields depend on that state.

An example is an object that is imported into a database with a long task. The app will write a record to the database to indication that it's currently being imported, and locking it from other writers.

We might model that with two interfaces: ImportingFoo, and ImportedFoo, discriminated by a status field:

type FooStates = ImportingFoo | ImportedFoo;

interface ImportingFoo {
  status: 'importing';
  value: undefined;
}

interface ImportedFoo  {
  status: 'imported';
  value: string;
}

We want our class to implement this type to indicate what type value can be depending on the type of status:

class Foo implements FooStates {
  status: 'importing' | 'imported' = 'importing';
  value: undefined | string;
}

This currently gives a "A class can only implement an object type or intersection of object types with statically known members.(2422)" error.

If we could do that, we could use narrowing for the instance:

const getValue = (foo: Foo): string => {
  if (foo.status === 'imported') {
    return foo.value; // OK, because foo narrowed to a ImportedFoo
  }
  throw new Error('Invalid state');
}
💻 Use Cases
  1. What do you want to use this for?
  • Classes that act as discriminated unions
  1. What shortcomings exist with current approaches?
  • The class can't explicitly implement the union, narrowing doesn't automatically work
  1. What workarounds are you using in the meantime?
  • Cast the instance to an intersection of the class and interface: foo as Foo & ImportedFoo, but this is error prone as the cast will succeed in cases where it shouldn't.

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

Commencez par suivre la validation de implements des classes qui produit le diagnostic 2422, puis examinez le fonctionnement du narrowing des unions discriminées pour les instances de classes. Comparez les exemples proposés FooStates et Foo, et identifiez les tests du compilateur couvrant l’implémentation des classes et le narrowing. C’est terminé lorsque les implémentations d’unions valides sont acceptées et que la vérification foo.status montrée réduit correctement foo.value sans modifier la sortie JavaScript.

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é
Plutôt claire
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

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