Because of this, I use the < T > generic in my “Types” module: (the stack is built upon tables, contents is just what is in the stack at any point)
--!strict
local Types = {}
export type Stack<T> = {
contents: {T},
max_size: number,
}
return Types
Then I have a stack methods module. One of the functions here is “push”, which will accept two parameters: A stack and some data to be pushed onto said stack.
However, when the function first runs, I want to make sure that the types of the parameters are what they should be. This was quite trivial with checking the stack objects contents field and max_size field, but I’m struggling checking the type of the data parameter.
Essentially, if I pass in a stack of numbers, the data I try to push should also be a number.
But if I pass in a stack of strings, the data I try to push should be a string.
--!strict
-- Services
local ServerScriptService = game:GetService("ServerScriptService")
-- Modules
local Types = require(ServerScriptService.Types)
local StackMethods = {}
function StackMethods.push<T>(stack_object: Types.Stack<T>, data: T)
-- Check the parameters are of the correct type
assert(typeof(stack_object.contents) == "table", "Expected table for stack contents, recieved: "..typeof(stack_object.contents))
assert(typeof(stack_object.max_size) == "number", "Expected number for stack max size, recieved: "..typeof(stack_object.max_size))
assert(typeof(data) == T) -- Cant get this to work!!!!!!!!!!!!!!!!!
end
return StackMethods
Currently, the linter is saying “Unknown global ‘T’”
So how could I throw an error if the type of data wasn’t T?
I don’t believe that you need to do any checks for the type. The function only takes in T, so it makes no sense to be checking whether data is T, when it always will be.
Luau type checking is static, so it’s not possible to do what you’re trying to do without using some runtime type checking library like t. However, this would make implementation quite a bit messier because the stacks would need to store the typecheck function.
export type Stack<T> = {
contents: { T },
max_size: number,
-- Would need to add this:
verifier: (any) -> boolean,
}
-- e.g. newStack(128, t.string) if you're using t
local function newStack<T>(maxSize: number, verifier: (any) -> boolean): Stack<T>
return {
contents = table.create(maxSize),
max_size = maxSize,
verifier = verifier,
}
end
function StackMethods.push<T>(stack_object: Stack<T>, data: T)
assert(
typeof(stack_object.contents) == "table",
"Expected table for stack contents, recieved: " .. typeof(stack_object.contents)
)
assert(
typeof(stack_object.max_size) == "number",
"Expected number for stack max size, recieved: " .. typeof(stack_object.max_size)
)
assert(stack_object.verifier(data))
end
That being said, it’s completely the user’s fault if they ignore the lint error. I don’t think trying to resolve this will be worth your time.