microsoft / microsoft/TypeScript

Allow classes to implement unions of object types

Abierto
#62,630 17 comentarios 4 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Awaiting More Feedback Suggestion
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
2 d 4 h
PR fusionados (30 d)
132

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza rastreando la validación de implements de las clases que produce el diagnóstico 2422 y, después, inspecciona cómo funciona el narrowing de uniones discriminadas para las instancias de clase. Compara los ejemplos propuestos FooStates y Foo, e identifica las pruebas del compilador que cubren la implementación de clases y el narrowing. Se considera terminado cuando se aceptan las implementaciones de unión válidas y la comprobación mostrada de foo.status estrecha correctamente foo.value sin cambiar la salida de JavaScript.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.