I wrote this function to check if the values being sent of remote events were the correct type. But I can’t help but think there is a better of more efficient way of doing this.
Here is my code:
--!strict
type TypeValidator = (...any) -> (boolean, string?)
type ReturnType = {
strict: (checkFor: string) -> (ReturnType),
optional: (checkFor: string) -> (ReturnType),
construct: () -> (TypeValidator)
}
return function(): ReturnType
local typeCheckers: { [number]: TypeValidator } = {}
local methods
local minArguments = 0
local maxArguments = 0
local function check(...: any): (boolean, string?)
local arguments = select("#", ...)
if arguments < minArguments or arguments > maxArguments then
return false, string.format(
"Expected %d arguments, got %d.",
arguments < minArguments and minArguments or maxArguments,
arguments
)
end
for i = 1, arguments do
local argument = select(i, ...)
local success: boolean, errorMessage: string? = typeCheckers[i](argument)
if not success then
return false, errorMessage
end
end
return true
end
local function strict(checkFor: string): ReturnType
minArguments = minArguments + 1
maxArguments = maxArguments + 1
table.insert(typeCheckers, function(value: any)
if checkFor == "any" then
return true
end
local gotType = typeof(value)
if gotType == checkFor then
return true
else
return false, string.format("Expected %q, got %q.", checkFor, gotType)
end
end)
return methods :: ReturnType
end
local function optional(checkFor: string): ReturnType
maxArguments = maxArguments + 1
table.insert(typeCheckers, function(value)
if checkFor == "any" or value == nil then
return true
end
local gotType = typeof(value)
if gotType == checkFor then
return true
else
return false, string.format("Expected %q or \"nil\", got %q.", checkFor, gotType)
end
end)
return methods :: ReturnType
end
local function construct(): (...any) -> (boolean, string?)
return check
end
methods = {
strict = strict,
optional = optional,
construct = construct
}
return methods
end
Here is a sample use case:
local TypeValidator = require(path.to.module)
local CheckType = TypeValidator().strict("boolean").optional("number").construct()
RemoteEvent.OnServerEvent:Connect(function(a: boolean, b: number)
local success: boolean, errorMessage: string? = CheckType(a, b)
if not success then
error(errorMessage :: string, 2)
end
--do something
end)