@dalokey/enumerator
Version:
A container for a finite set of elements that provides various enumeration functionality.
148 lines (131 loc) • 5.29 kB
text/typescript
/**
* Represents an enum object
*/
interface IEnumObject<T> {
[key: string]: any,
Name: string,
Value: T | null,
}
/**
* Defines a generalised function that expects a value types or class to have equal instances.
*/
interface IEquatable<T, TValue> {
equals(other: Enumerator<T, TValue>): boolean,
}
/**
* Represents an enum class/element constructor
*/
interface IConstructor<T, TValue> {
new(n: string, v: TValue) : T,
}
/**
* This class contains enumeration features
*/
export abstract class Enumerator<TK, TKValue> implements IEquatable<TK, TKValue>{
/**
* Used to get an enum element by its name.
* Will return the first element found if there are more than one with the same name.
* @param type The enum class type
* @param name The name of the enum element
* @param defaultValue The default enum element returned if the return value is undefined
* @example
* let blueEnum = Enumerator.getByName(ColourType, "blue");
* @returns enum element found | enum if provided | undefined
*/
public static getByName = <T, TValue>(type: IConstructor<T, TValue>, name: string, defaultValue?: Enum<T, TValue>)
: Enum<T, TValue> | undefined => {
if (!name?.trim()) {
return defaultValue;
}
return this.getAll(type).find(x => x.Name == name) ?? defaultValue;
}
/**
* Used to get an enum element by its value.
* Will return the first element found if there are more than one with the same value.
* @param type The enum class type
* @param value The value of the enum element
* @param defaultValue The default enum element returned if the return value is undefined
* @example
* let blueEnum = Enumerator.getByValue(ColourType, 1002);
* @returns enum element found | enum if provided | undefined
*/
public static getByValue = <T, TValue>(type: IConstructor<T, TValue>, value: TValue, defaultValue?: Enum<T, TValue>)
: Enum<T, TValue> | undefined => {
if (!value) {
return defaultValue;
}
return this.getAll(type).find(x => x.Value == value) ?? defaultValue;
}
/**
* Used to check if an enum element with the provided name exists.
* @param type The enum class type
* @param name The name of the enum element
* @example
* let blueEnum = Enumerator.isNameValid(ColourType, "blue");
* @returns boolean
*/
public static isNameValid = <T, TValue>(type: IConstructor<T, TValue>, name: string): boolean => {
return this.getAll(type).find(x => x.Name == name) ? true : false;
}
/**
* Used to check if an enum element with the provided value exists.
* @param type The enum class type
* @param value The value of the enum element
* @example
* let blueEnum = Enumerator.isValueValid(ColourType, 1002);
* @returns boolean
*/
public static isValueValid = <T, TValue>(type: IConstructor<T, TValue>, value: TValue): boolean => {
return this.getAll(type).find(x => x.Value == value) ? true : false;
}
/**
* Used to get an array containing all the enum elements.
* @param type The enum class type
* @example
* let listOfColourEnums = Enumerator.getAll(Colour);
* @returns Array of enum elements
*/
public static getAll = <T, TValue>(type: IConstructor<T, TValue>): Enum<T, TValue>[] => {
let propertyNames = Object.getOwnPropertyNames(type);
let enums: Enum<T, TValue>[] = [];
let _type: any = type;
for (let i = 0; i < propertyNames.length; i++) {
let propertyName = propertyNames[i];
if (_type[propertyName] instanceof _type) {
enums.push(_type[propertyName]);
}
}
return enums;
}
/**
* This function can be used to check if enum elements are equal
* @param other The other enum to check against
* @example
* let isRedMyFavoriteColour = Colour.Red.equal(colour);
* @returns boolean
*/
public abstract equals(other: Enum<TK, TKValue>): boolean;
}
/**
* Representation of an Enum class. This class can be implemented by other classes to allow the use of this package's features
*/
export abstract class Enum<T, TValue> implements Enumerator<T, TValue>, IEnumObject<TValue>{
/**
* Represents the derived class constructor
* @param Name The enum element's name. The assigned value can not be changed once the enum element is created
* @param Value The enum element's value. The assigned value can not be changed once the enum element is created
*/
constructor(public readonly Name: string, public readonly Value: TValue){
}
/**
* This function can be used to check if enum elements are equal
* @param other The other enum to check against
* @example
* let isRedMyFavoriteColour = Colour.Red.equal(colour);
* @returns boolean
*/
equals = (other: Enum<T, TValue>): boolean => {
if (!other) { return false };
return this == other;
}
}