Review my Enum customer

--OBJECT (class)
local EnumObject = {}
EnumObject.__index = EnumObject

type enumInfo = {
	Name: string,
	Value: number,
	EnumType: string
}

function EnumObject.new<T>(enumType: string, enumTable: T): self
	local self = setmetatable({}, EnumObject)
	
	self.enumItems = {}:: T
	
	for _, v: string in enumTable do
		local tableAdded = {
			Name = v,
			Value = (#self.enumItems + 1),
			EnumType = enumType
		}
		
		self.enumItems[v] = tableAdded
	end
	
	return self
end

function EnumObject:checkForAll(enumItem: enumInfo)
	local thisEnumItem = self.enumItems[enumItem.Name]:: enumInfo
	
	return thisEnumItem.Value == enumItem.Value and thisEnumItem.EnumType == enumItem.EnumType
end

function EnumObject:check(firstItem: enumInfo, secondItem: enumInfo)
	if not self.enumItems[firstItem.Name] or not self.enumItems[secondItem.Name] then return end
	
	return firstItem.Value == secondItem.Value and firstItem.Name == secondItem.Name and firstItem.EnumType == secondItem.EnumType
end

export type self = typeof(EnumObject.new(...))

return EnumObject


--Enums module

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local Modules = ReplicatedStorage.Modules

local EnumObject = require(Modules.Contents.Enum.Enum)

local Enums = {
	AurasEvent = EnumObject.new("AurasEvent", {
		Reroll = "Reroll",
	})
}

return Enums

--in script

local enums = require(game.ReplicatedStorage.Modules.Controller.Enums)
local enumItem = enums.AurasEvent.enumItems.Reroll

print(enums.AurasEvent:check(enumItem, enumItem)) -- for this exemple i use two times my variable (its normal)
print(enums.AurasEvent:checkForAll(enumItem)) -- For other dataCheck exemple if a == "a" or a == "b"

--Output: print(true)
--Output: print(true)

Everything looks pretty fine, only 2 minor things get my eyes (and mind) sore a bit.

Value = (#self.enumItems + 1),

I think when you iterate through the enumTable you get the index, which is count, as the first tuple value which you had ignored as _, right? I think you can just use it…

local self = setmetatable({}, EnumObject)

Classic move, not much wrong with that.
In my own prod, I use it when defining self only if i need to invoke any of the metatable functions in the .new func. Otherwise:

local self = {}

...

return setmetatable(self, EnumObject)

Also, while writing this, the enumItems list can be assigned on self definition.

In conclusion:

local self = {
    enumItems = {} :: T
}

for i: number, v: string in enumTable do
    local tableAdded = {
        Value = i,
        Name = v,
        EnumType = enumType
    }
    
    self.enumItems[v] = tableAdded
end

return setmetatable(self, EnumObject)

Personal way I’d refactor it.
Don’t take to heart too much, this is mostly my own taste, based on what I’ve wrote throughout the years