microsoft / microsoft/TypeScript

Spreading object with optional property causes incorrect type inference when `exactOptionalPropertyTypes = false`

Abierto
#62,906 3 comentarios 1 reacción 0 asignados Ver en GitHub
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

spread optional property undefined

### 🕗 Version & Regression Information

5.9.3 and others

### ⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.9.3#code/MYewdgzgLgBAhjAvDA3jAHgLhgFgEwwC+AsAFCiSwBGAjEqhtgK5gAmApgGYCWY7rRMhWgxgdZGgB00uABoY0ybSIwA9KphQAngAd2MEJ1F1uEGL07sATlf7wzaLDBYcefVgG4VAWk0ALOCgAcjNQG3ZgWEBQciFwCBAAG3ZJBJAAcwAKMQBKMljKGCo8bEcAfmwwJgBbKmsVCUZnNi5eO0I1DSg-UxhWEHYzMBBYHSsQViZgfTgwGGsxqxgAdz92WfZ0OEiAeR0obnA4BIAFMb0rbQAVXQHETiOIdnyRYAIGxTkFaSKVdU0bgxGV7mMwWeZ2OAORqVGrWLztXxdQIhZZjMBpeSQ0R4SToGAAfVM+KarlaAkAMuTPRLJVKZV65UhAA

### 💻 Code

```ts
const a = { x: 42 }
const b1 = { x: undefined }
const c1 = { ...a, ...b1 } // type of c1 is inferred as { x: undefined; } - that's correct ✅
console.log(c1)

const b2: { x?: number } = { x: undefined } // this does not produce an error when exactOptionalPropertyTypes=false
const c2 = { ...a, ...b2 } // type of c2 is inferred as { x: number; } - that's wrong, as c2.x _is_ undefined ❌
console.log(c2)
```

### 🙁 Actual behavior

I know that there have been several issues filed before like https://github.com/microsoft/TypeScript/issues/57086 / https://github.com/microsoft/TypeScript/issues/51755 / https://github.com/microsoft/TypeScript/issues/51253 / https://github.com/microsoft/TypeScript/issues/57408 and they all were closed referring to `exactOptionalPropertyTypes`.

However, reading the docs, the [description of `exactOptionalPropertyTypes`](https://www.typescriptlang.org/tsconfig/#exactOptionalPropertyTypes) says:

> exactOptionalPropertyTypes makes TypeScript truly enforce the definition provided as an optional property:
>
> const settings = getUserSettings();
> settings.colorThemeOverride = "dark";
> settings.colorThemeOverride = "light";
>
> // But not:
> settings.colorThemeOverride = undefined;
> > Type 'undefined' is not assignable to type '"dark" | "light"' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target.

So, the option changes the way, **how `?:` is defined** from "can be not present or undefined" to "can be not present, but not set to undefined".

But even when `exactOptionalPropertyTypes=false`, I don't see a reason why TS should infer an _invalid_ type in the example given above. It _knows_ that `x` can be undefined (or not present) and it _knows_ that `exactOptionalPropertyTypes=false`, so it should really infer in this case that the prop value _can_ be undefined. For me, that would appear to be a consistent implementation of the language semantics.

Or do I miss something?

### 🙂 Expected behavior

I want to rely on TS inferring correct types, also in this case.

### Additional information about the issue

Of course, this change would be a breaking change, so there could be another option to activate it.

We have a large project and there are many places (including JSON stored in customer DBs) that would need to be adjusted if we want to set `exactOptionalPropertyTypes` to true. So that's not a solution we can quickly implement.

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Comienza con el ejemplo enlazado de TypeScript Playground y compara sus tipos inferidos con diferentes configuraciones de exactOptionalPropertyTypes. Lee las issues relacionadas #57086, #51755, #51253 y #57408 para entender las decisiones anteriores. Se considera terminado cuando el resultado del spread en el caso reportado refleja que x puede ser undefined sin requerir que exactOptionalPropertyTypes esté habilitado.

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
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.