Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enumerate String Literal Union Values at Runtime #13542

Closed
battmanz opened this issue Jan 17, 2017 · 7 comments
Closed

Enumerate String Literal Union Values at Runtime #13542

battmanz opened this issue Jan 17, 2017 · 7 comments
Labels
Duplicate An existing issue was already created

Comments

@battmanz
Copy link

battmanz commented Jan 17, 2017

TypeScript Version:
2.1.4

Code

// Would like to do this:
type Greeting = 'hi' | 'hola' | 'hallo' | 'salut';
const allGreetings: Greeting[] = keyof Greeting; // Error!

// Currently, I am forced to do this:
type Greeting = 'hi' | 'hola' | 'hallo' | 'salut';
const allGreetings: Greeting[] = ['hi', 'hola', 'hallo', 'salut'];

Expected behavior:
I have a need to get all values from a String Literal Union Type at runtime as an array. It would be great if the keyof operator (or some other operator) provided this functionality.

Actual behavior:
Currently, there is no way to do this besides just manually copying all of the values into an array.

@RyanCavanaugh
Copy link
Member

Is #3192 what you actually want?

@battmanz
Copy link
Author

battmanz commented Jan 17, 2017

I believe that would suit my needs. However, assuming that the language had both string enums and string literal unions, I think I would be torn between which to use. Would the rule be to use a string enum when you want to enumerate the values and otherwise use a string literal union?

They both seem to accomplish the same thing in different ways.

@RyanCavanaugh
Copy link
Member

I think the difference would simply be whether or not you wanted the strings to be available at runtime. The type system is always fully erased so there's not going to be a way to emit different code depending on what a type system object is (see https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals)

@mhegazy mhegazy added the Duplicate An existing issue was already created label Jan 18, 2017
@battmanz
Copy link
Author

Just out of curiosity, how is it that enums don't break the "fully-erasable type system" rule? I mean, enums don't exist in JavaScript. So I would consider them to be part of the type system, but they are not erased at runtime. They are compiled into a two-way associative array. So how would it be any different to emit an array of string literal values at runtime? I just want to increase my understanding. Thanks!

@RyanCavanaugh
Copy link
Member

The type system is erased (consider how generics are erased in Java even though generic classes still create code) but declarations which are specified to create values still create values.

The distinction here is that you can syntactically analyze (not typecheck) a file and produce the correct JavaScript; this would not be true for an unerased type system. Basically, the type of any given expression (as determined by the checker) does not change how it behaves at runtime.

@battmanz
Copy link
Author

@RyanCavanaugh thanks for the quick reply and such a good reply at that! It's going to take some time for me to digest everything that you said.

But in the meantime, it sounds like string-based enums are the way to go. So I'm going to close this bug.

@pelotom
Copy link

pelotom commented Feb 27, 2017

Hi, check out my library runtypes for a solution to this problem. Example usage:

// Define the runtype
const Day = Union(
  Literal('Sunday'),
  Literal('Monday'),
  Literal('Tuesday'),
  Literal('Wednesday'),
  Literal('Thursday'),
  Literal('Friday'),
  Literal('Saturday'),
)

// Extract the static type
type Day = Static<typeof Day> // = 'Sunday' | 'Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday'

// Extract enumerated literal values
const days: Day[] = Day.alternatives.map(lit => lit.value)

for (const day of days) {
  console.log(`Good morning, it's ${day}!`)
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants