microsoft / microsoft/TypeScript

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

Ouverte
#62,906 3 commentaires 1 réaction 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

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.

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 l’exemple TypeScript Playground lié et comparez ses types inférés avec différents paramètres de exactOptionalPropertyTypes. Lisez les issues associées #57086, #51755, #51253 et #57408 pour comprendre les décisions précédentes. C’est terminé lorsque le résultat du spread dans le cas signalé reflète que x peut être undefined sans nécessiter l’activation de exactOptionalPropertyTypes.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Bug
Difficulté
5/5
Temps estimé
Plus d'une semaine
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

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