Ralph
Ralph

Reputation: 32294

Enumerate TypeScript string literals

Is there any way to loop over the values of a TypeScript string literal?

type category = "foo" | "bar" | "baz" | "xyzzy"

for (c in category) {
    // ... do something with each category
}

I currently have something like this:

let cat: category = ...

switch (cat) {
    case "foo":
    default:
        process("foo")
        break

    case "bar":
        process("bar")
        break

    case "baz":
        process("baz")
        break

    case "xyzzy":
        process("xyzzy")
        break
}

but I would rather use something like

let others: category = []
for (c in category) {      // Iterate over possible category values
    if (c !== "foo") others.push(c)
}

if (others.indexOf(cat) >= 0) {
    process(cat)
} else {
    process("foo")
}

Upvotes: 10

Views: 2577

Answers (2)

artem
artem

Reputation: 51689

With typescript 2.1 and keyof type, it's possible to do it the other way round - you can define an object with necessary keys, and get union type of all the keys using keyof:

let categoryKeys = {foo: '', bar: '', baz: '', xyzzy: ''}; // values do not matter

type category = keyof typeof categoryKeys;

let x: category = 'foo'; // ok
let z: category = 'z'; //  error TS2322: Type '"z"' is not assignable 
                       // to type '"foo" | "bar" | "baz" | "xyzzy"'.

console.log(Object.keys(categoryKeys)); // prints [ 'foo', 'bar', 'baz', 'xyzzy' ]

Upvotes: 15

TSV
TSV

Reputation: 7641

This is the type declaration.

type category = "foo" | "bar" | "baz" | "xyzzy"

TypeScript transpiles to JavaScript that has no types. Type in the TypeScript is just an information for transpiler about possible certain values (in this case). And type declaration is not compiled into any real runtime JavaScript object. Thus you can not iterate through it, but you can use it in switch construction.

Upvotes: 4

Related Questions