Skip to content

Deprioritise properties of the form { prop?: never } in completionsΒ #62024

Open
@LukeAbby

Description

@LukeAbby

πŸ” Search Terms

exact union properties, autocomplete prioritisation, completion prioritisation, never properties

βœ… Viability Checklist

⭐ 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

  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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions