mimir/mienum
MiEnum
a simple enum module for luau. nothing crazy, just makes working with enums cleaner and type-safe.
v2.0.0 — adds scoped enums and fixes error reporting to always point at your code.
what it does
- create enums that are frozen (immutable after creation)
- strict luau types so you can't accidentally pass a random number or string
- runtime checks to validate enum values
- look up items by name or value, or grab all of them
- union types if you need to combine enums
- scopes to group related enums and prevent name collisions
installation
drop the module here: ReplicatedStorage/ └── Packages/ └── MiEnum then require it:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MiEnum = require(ReplicatedStorage.Packages.MiEnum)
two ways to create enums
1. scoped enums (recommended)
scopes let you group related enums under a namespace and prevent name collisions across your project.
local GameEnums = MiEnum.NewScope("GameEnums")
local StatusEffectType = GameEnums.CreateEnum("StatusEffectType", {
Control = 1,
Torture = 2,
Positive = 3,
Negative = 4,
})
trying to create two scopes with the same name, or two enums with the same name in the same scope, will throw an error.
2. private enums (unscoped)
if you just need a quick local enum that isn't part of any shared scope:
local WeaponType = MiEnum.CreatePrivateEnum("WeaponType", {
Sword = 1,
Bow = 2,
Staff = 3,
})
use this for module-internal enums you don't want exposed globally.
definition rules
- keys must be unique strings
- values must be unique numbers
- reserved keys (
Count,GetEnumItems,FromName,FromValue,IsEnumItem,_Name) are not allowed - enums are frozen after creation — no changes after the fact
accessing items
print(StatusEffectType.Control) -- StatusEffectType.Control
print(StatusEffectType.Control.Name) -- "Control"
print(StatusEffectType.Control.Value) -- 1
print(StatusEffectType.Count) -- 4
every item has three fields: Name, Value, and EnumType (a reference back to the enum it belongs to).
strict types
export type StatusEffectType = typeof(StatusEffectType.Control)
now you can use it in function signatures:
local function ApplyStatus(effect: StatusEffectType)
print("Applying:", effect.Name)
end
ApplyStatus(StatusEffectType.Control) -- ✅
ApplyStatus(1) -- ❌ type error
ApplyStatus("Control") -- ❌ type error
combining enums
export type AnyStatusEffect = ControlStatusEffect | TortureStatusEffect | PositiveStatusEffect
local function ApplyAny(effect: AnyStatusEffect)
print(effect.Name)
end
lookup methods
-- by name (returns nil if not found)
local item = StatusEffectType:FromName("Control")
-- by value (returns nil if not found)
local item = StatusEffectType:FromValue(1)
-- all items, keyed by value
local items = StatusEffectType:GetEnumItems()
for value, item in items do
print(item.Name, value)
end
runtime checks
if StatusEffectType:IsEnumItem(value) then
print("valid item from this enum")
end
IsEnumItem checks that the value is an enum item and that it belongs to this specific enum — passing an item from a different enum returns false.
full example
local MiEnum = require(ReplicatedStorage.Packages.MiEnum)
local GameEnums = MiEnum.NewScope("GameEnums")
local WeaponType = GameEnums.CreateEnum("WeaponType", {
Sword = 1,
Bow = 2,
Staff = 3,
})
export type WeaponType = typeof(WeaponType.Sword)
local function Attack(weapon: WeaponType)
if WeaponType:IsEnumItem(weapon) then
print("Attacking with:", weapon.Name)
end
end
Attack(WeaponType.Bow) -- Attacking with: Bow
that's pretty much it. if something's broken or confusing feel free to open an issue.