microsoft / microsoft/TypeScript

Better error messaging for when property assignments fail due to intersection types

Abierto
#42,788 4 comentarios 2 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

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

Descripción

Bug Report

🔎 Search Terms

error messaging
not assignable to type 'never'

🕗 Version & Regression Information

This isn't an error, just a confusing error message for a corner case, so it's been in TypeScript for a while.

⏯ Playground Link

Playground link with relevant code

💻 Code
interface Person {
  name: string;
  age: number;
}

function copyPerson(original: Person, copyTo: Person) {
  for (const key of ["name", "age"] as const) {
    // Type 'string | number' is not assignable to type 'never'.
    //   Type 'string' is not assignable to type 'never'. (2322)
    copyTo[key] = original[key]; // error on copyTo[key]
  }
}

function copyPartialPerson(original: Partial<Person>, copyTo: Partial<Person>) {
  for (const key of ["name", "age"] as const) {
    // Type 'string | number | undefined' is not assignable to type 'undefined'.
    //   Type 'string' is not assignable to type 'undefined'. (2322)
    copyTo[key] = original[key]; // error on copyTo[key]
  }
}

🙁 Actual behavior

The error messages shown in the code above.

🙂 Expected behavior

An error message indicating that the right-hand side of the assignment must be assignable to the intersection of all possible types of the left-hand side of the assignment. The intersection part is specifically what seems to be hard to intuit about this error the first time someone encounters it. The never and undefined types being assigned to in the examples above seem to come out of nowhere.

One option is to add another level of messaging to the error, e.g.

Type 'string | number' is not assignable to type 'string & number'.
  Type 'string | number' is not assignable to type 'never'.
    Type 'string' is not assignable to type 'never'.
Type 'string | number | undefined' is not assignable to type '(string | undefined) & (number | undefined)'.
  Type 'string | number | undefined' is not assignable to type 'undefined'.
    Type 'string' is not assignable to type 'undefined'.

Another option is to special-case assignments that assign to $expr1[$expr2], and have an error message like Cannot assign type $assigneeType to $expr1[$expr2] for all values of $expr2. e.g.

Cannot assign type 'string | number' to 'copyTo[key]' for all possible values of 'key'.
  Type 'string | number' is not assignable to type 'never'.
    Type 'string' is not assignable to type 'never'.
Cannot assign type 'string | number | undefined' to 'copyTo[key]' for all possible values of 'key'.
  Type 'string | number | undefined' is not assignable to type 'undefined'.
    Type 'string' is not assignable to type 'undefined'.

That feels nicer, but we wouldn't want to have that error message any time a bad assignment is made to an index access. To only show the message at the appropriate time, a second check might be necessary, where the type-checker checks if the right-hand side would be assignable to the "read" type of the left-hand side. As in, if the following code would work:

let val = leftHandSideExpression;
val = rightHandSideExpression;

Then we can guess that the user is probably encountering this specific issue.

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 con el ejemplo enlazado de TypeScript Playground y el comportamiento del type-checker para asignaciones indexadas descrito en el issue. Compara los diagnósticos propuestos de estilo intersection y de asignación indexada, y luego localiza las pruebas y los diagnósticos relevantes del compilador; el issue no menciona archivos ni pruebas del repositorio. Se considera terminado cuando el confuso error never o undefined explica la restricción de intersection sin cambiar otros errores de acceso mediante índice.

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

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Error
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.