microsoft / microsoft/TypeScript
Deprioritise properties of the form `{ prop?: never }` in completions
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
### 🔍 Search Terms
exact union properties, autocomplete prioritisation, completion prioritisation, `never` properties
### ✅ Viability Checklist
- [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [x] This wouldn't change the runtime behavior of existing JavaScript code
- [x] This could be implemented without emitting different JS based on the types of the expressions
- [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- [x] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [x] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
### ⭐ Suggestion
It'd be nice if properties of the form `{ prop?: never }` were deprioritised in autocomplete. For example in this snippet:
```ts
const data: { a?: never; b: string } = { b: "foo" };
```
If you write `data.` you'll immediately get suggested `a` and then `b` but the property `a` may as well be useless in practice.
Similarly properties of the form `{ prop?: undefined }`, `{ prop: undefined }`, and `{ prop: never }` _could_ also be deprioritised. `{ prop?: undefined }` makes sense for better support for `"exactOptionalPropertyTypes": false` and the required variants are simply for consistency.
### 📃 Motivating Example
TypeScript assumes all objects can have excess keys. That can be a source of common confusion when snippets like this doesn't work:
```ts
function getData(): { a: string } | { b: string } {
return { a: "foo" };
}
getData().a;
// ^ Property 'a' does not exist on type '{ a: string; } | { b: string; }'.
// Property 'a' does not exist on type '{ b: string; }'.
```
Users generally expect this to simply be typed as `string | undefined`. A common pattern for overcoming this is adding properties like `{ b?: never }`. So common, in fact, that TypeScript itself produces it:
```ts
const data = Math.random() > 0.5 ? { a: "foo" } : { b: "bar" };
// ^ { a: string; b?: never } | { b: string; a?: never }
```
(if you see `b?: undefined` and `a?: undefined` that's because you don't have `exactOptionalPropertyTypes` enabled).
However the property completions are worsened due to this.
```ts
const data = Math.random() > 0.5 ? { a: "foo" } : { b: "bar" };
if (data.b === "foo") {
// `data` has been narrowed due to the above condition being impossible for `{ a: string; b?: never }`
data;
// ^ `{ a?: never; b: string }`
data.
// ^ `a` is suggested first despite being a completely useless property.
}
```
### 💻 Use Cases
1. What do you want to use this for?
Narrowed unions with `never` properties.
2. What shortcomings exist with current approaches?
Poor completion ordering.
3. What workarounds are you using in the meantime?
No workarounds are possible today as far as I know because the only control a user has over completion ordering is a property name.
贡献指南
调研方向
重现 issue 中的 `data.` 补全示例,包括缩小后的联合类型和 `exactOptionalPropertyTypes` 的各个变体。跟踪类型为 `never` 或 `undefined` 的属性的补全优先级路径,并在这些属性始终被降低优先级、且不改变类型检查或生成的 JavaScript 时视为工作完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- typescript
- 领域
- developer-experience, tooling
- Issue 类型
- 功能
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100