microsoft / microsoft/TypeScript

{} and { [K in never]: any } exhibit different simplification behavior

Abierto
#42,864 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Domain: Mapped Types
Lenguaje dominante
Go
Estrellas
111k
Forks
14.3k
Merge medio
1 d 19 h
PR fusionados (30 d)
117

Descripción

Bug Report

Under some circumstances, TypeScript treats { [K in never]: any } & { foo?: number } differently than {} & { foo?: number }. However, this does not occur with { [K in never]: any } & { foo: number }.

🔎 Search Terms

empty mapped object type, intersection with optional object, K in never

🕗 Version & Regression Information

Tested on 4.0.5, 4.1.5, 4.2.0-beta, and the current nightly

⏯ Playground Link

Playground link

💻 Code
type AreAllStringsTs<T> = string extends T ? true : false;
type Test1 = AreAllStringsTs<{ foo?: number }>;                         // expected: false, actual: false
type Test2 = AreAllStringsTs<{ foo: number }>;                          // expected: false, actual: false
type Test3 = AreAllStringsTs<string | number>;                          // expected: true,  actual: true
type Test4 = AreAllStringsTs<{ [K in never]: any } & { foo?: number }>; // expected: false, actual: true  <-- FAIL
type Test5 = AreAllStringsTs<{ [K in never]: any } & { foo: number }>;  // expected: false, actual: false
🙁 Actual behavior

Test4 is true.

🙂 Expected behavior

Test4 is false.

Potential Workaround

If you have a mapped object type in which the type expression for the keys might reduce to never, add a conditional check to see if the keys set is empty. For example, I encountered this when working with a type that would make all keys of an object that could take on the value undefined optional:

type Optionalize<T> =
    { [K in RequiredKeys<T>]: T[K] }
    & { [K in NonRequiredKeys<T>]?: T[K] };

Adding a check for never made the behavior consistent with what I was expecting when every field of the input type accepted undefined:

type Optionalize<T> =
    (RequiredKeys<T> extends never ? {} : { [K in RequiredKeys<T>]: T[K] })
    & { [K in NonRequiredKeys<T>]?: T[K]; };

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 enlace de Playground proporcionado y reproduce la diferencia entre Test4 y Test5. Traza cómo el compilador simplifica el tipo mapeado vacío cuando se intersecta con tipos de objeto opcionales y obligatorios. Se considera terminado cuando Test4 se evalúa como false, mientras que las demás expectativas indicadas permanecen sin cambios.

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
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.