microsoft / microsoft/TypeScript
Spreading object with optional property causes incorrect type inference when `exactOptionalPropertyTypes = false`
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
### 🔎 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.
贡献指南
调研方向
从链接的 TypeScript Playground 示例开始,并比较其在不同 exactOptionalPropertyTypes 设置下推断出的类型。阅读相关 issue #57086、#51755、#51253 和 #57408,以了解之前的决策。当所报告案例中的展开结果反映出 x 可能为 undefined,且不要求启用 exactOptionalPropertyTypes 时,即表示完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- typescript
- 领域
- compilers
- Issue 类型
- 缺陷
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100