Description
π Search Terms
exact union properties, autocomplete prioritisation, completion prioritisation, never
properties
β Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- 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:
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:
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:
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.
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
- What do you want to use this for?
Narrowed unions withnever
properties. - What shortcomings exist with current approaches?
Poor completion ordering. - 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.