Skip to content

Instantly share code, notes, and snippets.

@hieunc229
Last active January 2, 2019 14:14
Show Gist options
  • Save hieunc229/672b63957c6976c9482749152de435c9 to your computer and use it in GitHub Desktop.
Save hieunc229/672b63957c6976c9482749152de435c9 to your computer and use it in GitHub Desktop.
A typesafe enum implementation for JavaScript
class Enum {
constructor(type) {
Enum.initEnumType(type);
this.type = type;
}
/**
* Initate enum values ** Internal use only
* Iterate through given values and intiate enum value object
*/
initValues(values) {
var type = this.type;
for (let i = 1; i < values.length; i++) {
// Shape of enum value object
const enumObj = {
strValue: values[i],
intValue: i,
type: type,
toString: () => values[i]
};
// Assign enum value as string to `this`
Object.defineProperty(this, values[i], {
value: enumObj,
writable: false
})
// Assign enum value as int to `this`
Object.defineProperty(this, i, {
value: enumObj,
writable: false
})
};
// Turn on immutable
Object.freeze(this);
}
/**
* Check if an enum value belong to this type
* enumValue: an enum value object
*/
has(enumValue) {
return enumValue.type === this.type && enumValue.strValue in this;
}
/**
* @Override
* Display enum as its type (string)
*/
toString() {
return this.type;
}
}
Enum.initEnumType = function(type) {
if (window.__GLOBAL__ENUM__TYPES == undefined) {
// Case 1. No enum has been initated yet
// Initiate __GLOBAL__ENUM__TYPES and store enum types as string
window.__GLOBAL__ENUM__TYPES = [type];
} else if (window.__GLOBAL__ENUM__TYPES.indexOf(type) > -1) {
// Case 2. Enum type has already existed
// Throw error
throw new Error(`Enum type "${type}" has already existed`);
} else {
// Case 3. __GLOBAL__ENUM__TYPES already existed and enum type has not existed
// push new type to __GLOBAL__ENUM__TYPES
window.__GLOBAL__ENUM__TYPES.push(type);
}
}
Enum.init = function() {
let rs = new Enum(arguments[0]);
rs.initValues(arguments);
return rs;
}
/**** Usage ****
* Enum.init(typeName, value1, value2, ..., valueN)
****************/
var Types = Enum.init('Types', 'Number', 'String', 'Boolean');
var isEnumValueAType = Types.has(Types.Number);
// More at https://jsfiddle.net/hieunc229/69o7mped/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment