1

Node Version: 6.11.3

Typescript Version: 2.1.6

We have a bunch of enums in our project that mostly look like this:

export type ThingType = "thing1" | "thing2";

export namespace ThingType {
    export const THING_ONE = "thing1";
    export const THING_TWO = "thing2";
}

I want to expose these values in an endpoint for consumers of the endpoints that require these string values. So I've made an endpoint that looks like this:

const enums = {
    thingType: ThingType,
    ...
}

Which returns json looking like:

"data": {
    "thingType": {
        "THING_ONE": "thing1",
        "THING_TWO": "thing2"
    }
}

I want it to be output like:

"data": {
    "thingType": ["thing1", "thing2"]
}

For a plain javascript object, that would be fairly easy, I'd just add values() to the end of ThingType in my endpoint. But values() does not exist on namespaces or enums in TS. I haven't found anything in the docs on namespaces in Typescript but I feel there's gotta be something that would let me get the enum values easily.

Mike Manfrin
  • 2,597
  • 1
  • 22
  • 38

1 Answers1

4

Namespaces are compiled into plain javacsript objects, so Object.values() works as expected (in the environment that supports Object.values of course):

export type ThingType = "thing1" | "thing2";

export namespace ThingType {
    export const THING_ONE = "thing1";
    export const THING_TWO = "thing2";
}

const enums = {
    thingType: Object.values(ThingType)

}
console.(enums);

shows

{ thingType: ['thing1', 'thing2'] }

If Object.values is not available it gets a little more verbose:

const enums = {
    thingType: Object.keys(ThingType).map(k => ThingType[k])

}
artem
  • 29,391
  • 6
  • 61
  • 63
  • What version of ts? I'm getting an error saying `values does not exist on type ObjectConstructor` :/ – Mike Manfrin Oct 20 '17 at 21:31
  • Ahh, shoot, looks like its node7+, we are on node 6 right now https://stackoverflow.com/a/40421941/1329321 – Mike Manfrin Oct 20 '17 at 21:32
  • @MikeManfrin - Simple workaround for `object.values` being unavailable: https://stackoverflow.com/questions/38748445/uncaught-typeerror-object-values-is-not-a-function-javascript/38748490#38748490 – tymeJV Oct 20 '17 at 21:35
  • Yeah -- but that requires a map for each; which isn't terrible, just less concise than I was aiming for. I am using lodash as per the suggestion in https://stackoverflow.com/questions/40421825/how-to-use-object-values-on-server-side-in-node-js but just bummed there's nothing native that can handle it. – Mike Manfrin Oct 20 '17 at 21:36
  • Going to leave the question up just in case someone has a deeper understanding of ts that may point out something part of TS itself that can do this. – Mike Manfrin Oct 20 '17 at 21:37
  • I added workaround almost identical to the one suggested by tymeJV. `Object.values()` is not considered part of the language, it's part of the library, and TypeScript does not in general provide polyfills or replacements for missing library features - [with some exceptions](https://blog.mariusschulz.com/2016/12/16/typescript-2-1-external-helpers-library). But you may want to look into [--emitDecoratorMetadata](https://www.typescriptlang.org/docs/handbook/decorators.html#metadata) option to see if it emits something for namespaces and enums (I have no idea honestly) – artem Oct 20 '17 at 21:45