Last active
January 2, 2019 14:14
-
-
Save hieunc229/672b63957c6976c9482749152de435c9 to your computer and use it in GitHub Desktop.
A typesafe enum implementation for JavaScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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