Not planned
Description
Autocomplete works for literal string unions, but adding a union of string
negates autocomplete entirely. This has been brought up before but I believe there is enough value in this feature to be reconsidered.
My use case is to have a union of string literals for several colors, but also allow hex codes without having to add 16.7 million string literals.
TypeScript Version: 3.4.0-dev.20190202
Search Terms: Literal string union autocomplete
Code
interface Options {
borderColor: 'black' | 'red' | 'green' | 'yellow' | 'blue' | string
};
const opts: Options = {borderColor: 'red'};
Expected behavior:
Actual behavior:
Playground Link: https://stackblitz.com/edit/typescript-bwyyab
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
RyanCavanaugh commentedon Feb 4, 2019
From the compiler's point of view, this is just a very fancy way of writing
string
. By the time we're looking for suggestions atborderColor
, all the literals are lost.You could write something like this:

Naturally this doesn't stop you from writing
"bluck"
. You might want to track #6579sindresorhus commentedon Feb 4, 2019
Why not improve the compiler to keep more metadata around?
MrTarantula commentedon Feb 4, 2019
It may accomplish the same behavior, but that's not intuitive to me at all. I doubt I could have gotten there on my own, and I know I would have trouble explaining it to someone newly coming to TS from JS.
spcfran commentedon Mar 11, 2019
It would be great to have this built in, although understand it may be difficult to implement on the compiler.
In the meantime, a generic workaround based on @RyanCavanaugh's solution might help:
See it in action here
BendingBender commentedon Mar 12, 2019
Would be great if this could be implemented. It has the potential to improve even core Node.js APIs. The hash.digest
encondig
param, for example should accept plain strings but there are values available on all platforms that could be enumerated for ease of use.neurolag commentedon Jun 26, 2019
Hey Guys
Though the issue still isn't solved but I found out that in TS 3.5.1 you don't even have to create some weird property in order to get the workaround done:
While this code is perfectly valid, "hello", and "world" are still showing up in the autocompletion.
Thank you for this great fix, @RyanCavanaugh and @spcfran!
175 remaining items
iartemiev commentedon Jan 8, 2025
If I'm understanding correctly, the reason the suggested solutions work is that a union of a primitive type and some variation of an empty object produces the wrapper/boxed object type corresponding to that primitive.
For example,
string & Record<never, never>
appears to be equivalent toString
, the return type ofnew String('')
.This prevents the union from getting reduced to the wider type, as the compiler will not reduce a literal to an object type. However, assignability is preserved, so we're still able to assign an arbitrary string value in this case.
Is this the correct interpretation or am I making some incorrect assumptions along the way?