Hacker News new | ask | show | jobs
by justhelpingout 3111 days ago
You can certainly do this - you just need something to contain the enum since an enum is a nominal subtype of `number` already, so TypeScript unifies `number & anyEnum` to `number`.

The best tagging mechanism these days is `Nominal<T>` (which has no emit) or `As<T>` (which has a minimal amount of emit):

    interface Nominal<T> {
      'nominal type tag': T
    }

    class As<T> {
      private tag: T
    }
Both are used in the same manner:

    const enum SomeTag { }
    type Something = number & As<SomeTag>
    // or
    type Something = number & Nominal<SomeTag>
You can even avoid the boilerplate of `const enum` if you make the `T` of `As` or `Nominal` `T extends string`:

    type Something = number & As<'some:unique:string:tag'>
In both cases, the values are not unified, so:

    type Something = number & As<'kind1'>
    type SomethingElse = number & As<'kind2'>
    var x: Something = 123 as Something;
    var y: SomethingElse = 456 as SomethingElse;
    x = y;  // Type 'SomethingElse' is not assignable to type 'Something'.
1 comments

BTW the minimal emit of the class-based example will be removed by Webpack since the runtime representation is never used. Best option if you use a bundler.