UNPKG

enum-plus

Version:

A drop-in replacement for native enum. Like native enum but much better!

138 lines (132 loc) 3.94 kB
import { localizer } from "./localize.js"; import { ENUM_ITEM } from "./utils.js"; /** * Enum item class * * @template V General type for item value * @template K General type for item key * @template T General type for item initialization object */ export class EnumItemClass { /** * **EN:** The value of the enum item * * **CN:** 枚举项的值 */ value; /** * **EN:** The label of the enum item (also known as display name) * * **CN:** 枚举项的标签(亦称显示名称) */ label; /** * **EN:** The key of the enum item, which is the key in the initialization object when creating * the enum collection. * * **CN:** 枚举项的键,即创建枚举集合时初始化对象中的键 */ key; /** * **EN:** The original initialization object of the enum item, which is the sub-object of a * single enum item when creating the enum collection. * * **CN:** 枚举项的原始初始化对象,即创建枚举集合时单个枚举项的子对象 */ raw; /** * **EN:** A boolean value indicates that this is an enum item instance. * * **CN:** 布尔值,表示这是一个枚举项实例 */ [ENUM_ITEM] = true; #localize; #localizedProxy = new Proxy(this, { get: (target, prop) => { const origin = target[prop]; if (prop === 'label') { return target.toString(); } else if (typeof origin === 'function') { return origin.bind(target); } return origin; }, // Not allowed to edit set: (_, prop) => { /* istanbul ignore if */ if (!process.env.JEST_WORKER_ID) { console.warn(`Cannot modify property "${String(prop)}" on EnumItem. EnumItem instances are readonly and should not be mutated.`); } return true; }, defineProperty: (_, prop) => { /* istanbul ignore if */ if (!process.env.JEST_WORKER_ID) { console.warn(`Cannot modify property "${String(prop)}" on EnumItem. EnumItem instances are readonly and should not be mutated.`); } return true; }, deleteProperty: (_, prop) => { /* istanbul ignore if */ if (!process.env.JEST_WORKER_ID) { console.warn(`Cannot modify property "${String(prop)}" on EnumItem. EnumItem instances are readonly and should not be mutated.`); } return true; }, setPrototypeOf: () => { /* istanbul ignore if */ if (!process.env.JEST_WORKER_ID) { console.warn('Cannot change prototype of EnumItem. EnumItem instances are immutable.'); } return true; } }); /** * Instantiate an enum item * * @param key Enum item key * @param value Enum item value * @param label Enum item display name * @param raw Original initialization object * @param options Construction options */ constructor(key, value, label, raw, options) { this.key = key; this.value = value; this.label = label; this.raw = raw; this.#localize = content => { const localize = options?.localize ?? localizer.localize; if (typeof localize === 'function') { return localize(content); } return content; }; // @ts-expect-error: because override Object.toPrimitive method to return enum value this[Symbol.toPrimitive] = hint => { if (hint === 'number') { // for cases like Number(value) or +value return this.valueOf(); } else if (hint === 'string') { // for cases like String(value), `${value}` return this.toString(); } // for cases like '' + value, value == 1 return this.valueOf(); }; // Object.freeze(this); } readonly() { return this.#localizedProxy; } toString() { return this.#localize(this.label) ?? this.label; } toLocaleString() { return this.toString(); } valueOf() { return this.value; } } //# sourceMappingURL=enum-item.js.map