noob9527 / effective-enum

full functionality typescript enum type

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Build Status Coverage Status

effective-enum

for the time being, the typescript enum type is quite hard to use, this repo tries to implement a typesafe enum pattern described in the first edition of effective java

installation

via npm

npm install effective-enum --save

via yarn

yarn add effective-enum

getting started

import {EnumClass, EnumValue, EnumFactory} from 'effective-enum';

@EnumClass
class Color extends EnumFactory<Color>() {
    @EnumValue
    static readonly RED = new Color('红');
    @EnumValue
    static readonly BLUE = new Color('蓝');

    constructor(
        public label: string,
    ) {
        super();
    }
}

that's it, both Color and its instances are immutable, which means you can not add,remove or change a color after definition.

Color.values()              // => [Color.RED, Color.BLUE]
Color.of('RED')             // => Color.RED
Color.RED.toString()        // => "RED"
Color.RED.name              // => "RED"
JSON.stringify(Color.RED)   // => "RED"
Color.RED.label             // => "红"
Color.RED instanceof Color  // true

Color.BLACK = 'whatever'        // error
Color.RED.label = 'whatever'    // error
new Color()                     // error
Color()                         // error

drawback compare to typescript built in enum

In interface definition block, you can only use string/number/unique symbol as property keys. for example:

import {EnumClass, EnumFactory} from './index';

enum BuiltInColorEnum {
    RED = 'RED',
    BLUE = 'BLUE'
}

@EnumClass
class EffectiveColorEnum extends EnumFactory<EffectiveColorEnum>() {
    @EnumValue
    static readonly RED = new Color();
    @EnumValue
    static readonly BLUE = new Color();
}

interface SomeInterface {
    [BuiltInColorEnum.RED]: string;         // this should work
    [EffectiveColorEnum.RED]: string;       // compile time error
}

Anyway, one can make use of Merging Namespaces with Classes approach. to combine these two types of enum definition. e.g.

import {EnumClass, EnumValue, EnumFactory} from 'effective-enum';

namespace Color {
    export enum Constant {
        RED = 'RED',
        BLUE = 'BLUE',
    }
}

@EnumClass
export class Color extends EnumFactory<Color>() {
    @EnumValue
    static readonly RED = new Color();
    @EnumValue
    static readonly BLUE = new Color();
}

interface SomeInterface {
    [Color.Constant.RED]: string;
    [Color.Constant.BLUE]: string;
}

Color.RED.name              // => "RED"

license

MIT

About

full functionality typescript enum type


Languages

Language:TypeScript 97.1%Language:JavaScript 2.9%