1

I am looking for a string enum that can be iterated.

What I tried so far:

String union types:

type t = "p1" | "p2" | "p3"

Problem: Can't be iterated

Enum:

enum t { p1, p2, p3 }

Problem: can't have string enum

Object:

const t = {p1: "p1", p2: "p2", p3: "p3"}

Problem: can't strongly type a variable that should be "p1", "p2", or "p3"

I could use an object and string union types or an enum and a map but I end up repeating myself a lot. What is the proper way to get a string enum that you can iterate in typescript?

michaelmesser
  • 3,601
  • 2
  • 19
  • 42
  • This is javascript, it has strings, numbers, objects as types. It's not a statically typed language either. So you may want to rethink the problem you're trying to solve here and whether strong typing is what you need. – Callum Linington Jun 08 '16 at 17:48
  • @CallumLinington I tagged it typescript too. Typescript is a typed superset of javascript – michaelmesser Jun 08 '16 at 17:49
  • Well that changes everything... see [here](https://basarat.gitbooks.io/typescript/content/docs/enums.html) – Callum Linington Jun 08 '16 at 17:49
  • You're running into a limitation of Javascript, which doesn't have a representation for typing, or enums. See the link that David Sherret posted for how to represent in Javascript. – Alex Johnson Jun 08 '16 at 17:55

1 Answers1

1

I'm not sure why you need the value to be a string. Note that you can get the enum value from its name using t.p1 or t["p1"], and you can get it's name from its enum value using t[0].

For example:

enum t { p1, p2, p3 }

function foo(x : t) {
    console.log(`value: ${x}, name: "${t[x]}"`);
}
foo(t.p1);      // value: 0, name: "p1"
foo(t["p1"]);   // value: 0, name: "p1"

But if you really need to accept string values, you could always do this (yes, this would get pretty redundant after a while):

function foo(x : t | "p1" | "p2" | "p3") {
    if (typeof x == "string") x = t[x];
    console.log(`value: ${x}, name:"${t[x]}"`);
}

foo("p1");      // value: 0, name: "p1"
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331