A Simple Module for Creating Custom Enums

The Problem

For a long time now, I’ve been using strings to mimic enums. Although they work, I feel like I am always checking for any typos and mistakes while I’m typing the strings. Another downside to strings is that it doesn’t autofill for me!!! I have tried some modules out there but none of them seem to autofill which is what I need to prevent typos and make my work faster. And of course, the ability to create custom enums!


Behavior and Usage

This module simply creates Enums and EnumItems based on the EnumType. If you don’t know, here are some examples of EnumTypes and EnumItems. Enum.KeyCode and Enum.EasingStyle are both EnumTypes while Enum.RaycastFilterType.Blacklist is an EnumItem. Though, this module changes the Enum text to CustomEnum. Another thing is that userdata is used to create the individual enums which also ensures that it will be unique. I have also added an extra behavior that might be beneficial in some circumstances. That behavior is the ability to assign any value to the enum. Normally, you are limited to only numbers but here, you are able to assign any values such as instances, booleans, and cframes. And of course, you can’t assign nil values. As always, you are able to compare the enums as long as you are only comparing from one variable.


Creating our Enum

When requiring the module, it will return a function in which a string is needed as an argument. This will be your EnumType. Now, we will store our returned function in a variable to create our EnumItems.

local enumMetatable = require(enumMetatable)
local stateType = enumMetatable("State")

Creating our EnumItems

Now that we have established our Enum, we will then need to create the items. Currently, our EnumList is empty. We will create a table with our EnumItems. Why create a table you ask? Well this is where we can use Roblox’s autofill feature. When referencing a table, the indexes are able to be caught by Roblox’s script editor and give you autofill options! Now that we have solved the autofill problem, we just need to hook our EnumItems by calling the enumType variable we created

local stateType = enumMetatable("State")
local States = {
	Undefined = stateType("Undefined", 120),
	Playing = stateType("Playing"),
	Spectating = stateType("Spectating"),
}

-- The code autofills!
print(States.Undefined) --> CustomEnum.States.Undefined
print(State.Undefined.Value) --> 120
print(stateType == stateType ) --> true
print(stateType:GetEnumItems()) --> { [1] = "Undefined", [2] = "Playing", [3] = "Spectating" }

Alternatives

Now just in case you don’t care about autofill, there is a more compact way of formatting the code.
Instead of creating a new table for autofill, we will just use one variable and stuff all our EnumItems into one table. The one downside to this is that any methods like :GetEnumItems() (which is the only method right now unless you guys suggest adding something) will not work and won’t get referenced. Another downside is the inability to add custom values to each item. This time we will only be using strings and no indexes to create our table of EnumItems.

local States = enumMetatable("State") {
	"Undefined",
	"Playing",
	"Spectating"
}

-- No autofill :(
print(States.Undefined) --> CustomEnum.States.Undefined
print(States.Undefined == States.Undefined) --> true

Download

EnumMetatable.lua (1.9 KB)
https://create.roblox.com/marketplace/asset/13831439464/EnumMetatable

@TheManInCity (a.k.a. Templed)

18 Likes

Hey, awesome module, and it’s been a while, but is there a way to assign custom enums as a type?

What I mean is:

local EnumType = require(game:GetService("ReplicatedStorage").EnumTypes)("RecipeStep")
local StepEnums = {
	["Microwave"] = EnumType("Microwave"),
	["Bake"] = EnumType("Bake"),
	["Boil"] = EnumType("Boil"),
	["Fry"] = EnumType("Fry")
}

export type FoodRecipe = {EnumType} -- How would I refer to it as a type?

I’m wondering if it’s even possible, or I should just refer to it as any.

1 Like
export type FoodRecipe = typeof(StepEnums)
3 Likes