question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Intellisense String Unions autocomplete inconsistent with ts

See original GitHub issue

Bug Report

🔎 Search Terms

Intellisense String Unions Incorrect Autocomplete Types Typing

🕗 Version & Regression Information

This bug seems like it has been around since the introduction of String Unions.

The following example is of a type that will merge the keys of the input object into an ascending order (which as I write this bug template I notice it is not lexicographical order), since that’s how Typescript uses the individual types in the unions of types. This ordering is desirable since it is predictable. Without this order, the following StringConcatenationOrder type would be unusable, as would the other related types.

⏯ Playground Link


export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
  ? I
  : never;

export type UnionToOvlds<U> = UnionToIntersection<U extends any ? (f: U) => void : never>;
export type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;

export type StringConcatenationOrder<S extends string, SEPARATOR extends string> = PopUnion<S> extends infer SELF
  ? //
    SELF extends string
    ? Exclude<S, SELF> extends never
      ? `${SELF}`
      : // This works because the values of S are always interpreted in ascending lexiographical order
        `${StringConcatenationOrder<Exclude<S, SELF>, SEPARATOR>}${SEPARATOR}${SELF}`
    : never
  : never;

export type KeyCanBeString<K> = K extends number | boolean | string | null | undefined ? K : never;

export type OrderedCommaSeparatedKeysOfObject<T extends object> = OrderedCommaSeparatedKeys<`${KeyCanBeString<keyof T>}`>;
export type OrderedCommaSeparatedKeys<T extends string> = StringConcatenationOrder<T, ','>;

// @showEmit
const object = {
  _: 0,
  b: 0,
  a: 0,
  c: 0,
  1: 0
};

const replaced: OrderedCommaSeparatedKeysOfObject<typeof object> = '_,a,b,c,1';

Workbench Repro

🙁 Actual behavior

Screen Shot 2022-07-22 at 1 28 41 AM

In VS Code Intellisense looks at the object’s variable declaration order (_, b, a, c, 1), but ts will look at the ascending “lexicographical” order of the object keys (_,a,b,c,1).

In the workspace you can see it give an error, but ts compiles it. This throws me off sometimes since intellisense will present invalid completions that typescript will reject (correctly). Here’s the ts error thrown by Jest:

Screen Shot 2022-07-22 at 2 41 52 AM

🙂 Expected behavior

Intellisense should evaluate the object’s keys in the ascending order consistent with ts.

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
fatcerberuscommented, Jul 22, 2022

The order of types in a union is essentially arbitrary (based on the internal ID numbers of the types involved); type unions should generally be treated as unordered sets. Consistency between TS and IntelliSense is a moot point as the observed order of union constituents may change just by changing your code, or even just by renaming files so they get compiled in a different order. Any code that relies on a specific union order is indeed going to be very fragile, as you’ve observed here.

All may not be lost however - see #17944.

1reaction
MartinJohnscommented, Jul 22, 2022

Since I see the type here again, FYI: https://github.com/microsoft/TypeScript/issues/41857#issuecomment-740102743

We don’t support anything that involves UnionToIntersection; this is an ill-defined and will frequently produce “surprising” results.

Read more comments on GitHub >

github_iconTop Results From Across the Web

vscode intellisense donnot work when union types have ...
string is the base type of all string literal types (such as 't1' and 't2' ) This means as far as the compiler...
Read more >
TypeScript Interface Tutorial With Examples
In this tutorial, we will learn all about TypeScript Interfaces. We will also compare TypeScript Type vs Interface.
Read more >
User Manual - rust-analyzer
At its core, rust-analyzer is a library for semantic analysis of Rust code as it changes over time. This manual focuses on a...
Read more >
Python's “type hints” are a bit of a disappointment to me
The number and types of the columns aren't necessarily known at compile time. Which leads to runtime errors. Even in a statically typed...
Read more >
Functions returning unset by default (and divergent topics)
Whenever you see that String doesn't have a property you're looking ... Those inconsistencies are moot with Intellisense and autocomplete, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found