I would like to have a typed table, but I also like the autocomplete for the entries that Roblox Studio provides, since I know what’s in the table (if I type food., I can see all the entries in the food table).
The issue is that when I try to apply type checking to the table, the autocomplete stops working.
Example without types:
local food = {}
food.burger = {price = 100, category = "Main course"}
-- Autocomplete works, but a non-food object could be added to the table,
-- because the table doesn't have a specified type
-- Example:
food.cake = {pice = 100, category = "Dessert"}
-- Oops, the typo in "pice" could mess stuff up
Example with types (what I want):
type Food = {price: number, category: string}
local food: {[string]: Food} = {}
food.burger = {price = 100, category = "Main course"}
-- If I type "food.", I don't see the "burger" entry
-- However, I can't accidentally add a non-food object into the table
It’s pretty simple, just make a module script with the following code:
local MyFoodClass = {}
MyFoodClass.__index = MyFoodClass
function MyFoodClass.new(_price,_category)
local self = setmetatable({
-- Object properties go here
price = _price,
category = _category
}, MyFoodClass)
return self
end
function MyFoodClass:changePrice(newPrice)
self.price = newPrice
end
return MyFoodClass
local foodClass = require(SSS.FoodClass) -- Put the path of the module script here
local burger = foodClass.new(100,"Main Course")
print(burger.category) -- Main Course
print(burger.price) -- 100
burger:changePrice(120)
print(burger.price) -- 120
And as for the autocomplete, I have my timer object here using the class below, and you can see that Studio shows all of it’s properties in the script I created it in.
The autocomplete cannot evaulate your entire code at every point and determine the entries of every table you are working with. Therefore, unless you explicitly update the table in that line to have a ‘Burger’ value or create the table with a burger already in it, there is no way of knowing whether the table has a burger entry.
Additionally, this is not a safe practice for writing code. Relying on an autocomplete compiler can help you pick up spelling mistakes but you should write code to check for a burger entry before trying to use it.
From your original point, the best you can do is:
-- Create a food type, as you did
type FoodType = {
price: number,
category: string
}
-- Create a menu type but with an explicit index for "burger" and "cake".
type MenuType = {
burger: Food?,
cake: Food?
}
-- Could optionally wrap ["burger"] and ["cake"] to make clear that they are strings
local menu: MenuType = {}
menu.burger = {{
price = 100,
category = "Main"
}}
--| |
--| |
--| In later or other code |
--| |
--| |
-- check to see if the burger exists in the table because it could be nil
if (menu.burger ~= nil) then
-- do something with the burger, because you know it must be there.
end
This code above sets specific indexes for the menu but it will not tell you if the burger value is nil or has a table.