local Classy = {}
Classy.__index = Classy
function Classy:extend()
local Class = {}
Class.__index = Class
setmetatable(Class, {__index = self})
return Class
end
return Classy
And another module script acting as a class:
local Classy = require(game:GetService("ReplicatedStorage").Classy)
local AnimalClass = Classy:extend()
function AnimalClass.new(Name:string)
local Animal = setmetatable({}, AnimalClass)
Animal.Name = Name
return Animal
end
function AnimalClass:Speak()
print(self.Name)
end
return AnimalClass
Then I have a server-side script, but it doesn’t have autocomplete for the AnimalClass functions.
local AnimalClass = require(game:GetService("ReplicatedStorage").AnimalClass)
local Dog = AnimalClass.new("Dog")
Dog:Speak()
The lack of autocomplete in your AnimalClass module occurs because your code editor (likely Roblox Studio or another Lua environment) cannot infer the structure of AnimalClass due to its dynamic nature. To resolve this and enable autocomplete, you can use type annotations and LuaDoc comments to define your class structure explicitly.
Here’s how you can improve your module to include autocomplete support:
Improved Code with Autocomplete
Classy Module
You don’t need to change much here since it’s a base module:
local Classy = {}
Classy.__index = Classy
function Classy:extend()
local Class = {}
Class.__index = Class
setmetatable(Class, { __index = self })
return Class
end
return Classy
AnimalClass Module
Add type annotations and LuaDoc comments to explicitly define the structure of AnimalClass:
local Classy = require(game:GetService("ReplicatedStorage").Classy)
-- Define the AnimalClass type
export type AnimalClass = {
Name: string,
new: (Name: string) -> AnimalClass,
Speak: (self: AnimalClass) -> (),
}
local AnimalClass = Classy:extend()
-- Constructor
function AnimalClass.new(Name: string): AnimalClass
local Animal = setmetatable({}, AnimalClass) :: AnimalClass
Animal.Name = Name
return Animal
end
-- Speak method
function AnimalClass:Speak()
print(self.Name)
end
return AnimalClass
Server-Side Script
With the type annotations in place, your IDE (e.g., Roblox Studio with the Luau type checker) will now provide autocomplete:
local AnimalClass = require(game:GetService("ReplicatedStorage").AnimalClass)
-- Create a new instance of AnimalClass
local Dog = AnimalClass.new("Dog")
-- Autocomplete works for Dog:Speak()
Dog:Speak()
Key Improvements
export type:
The export type keyword explicitly defines the AnimalClass type, listing all its properties and methods. This helps the IDE recognize the structure of your class.
Type Annotations:
Adding Name: string and AnimalClass: AnimalClass makes the code self-documenting and aids in error checking.
Explicit Casting:
The :: AnimalClass cast tells the type checker that Animal conforms to the AnimalClass type.
Compatibility with Luau:
These changes leverage Roblox’s Luau type system, enabling autocomplete and catching type-related bugs during development.
Additional Tips
Documenting Methods:
Add LuaDoc-style comments above each method for extra clarity:
--- Makes the animal speak its name.
function AnimalClass:Speak()
print(self.Name)
end
Custom Types:
If you use more advanced class hierarchies, define shared types in a separate module for reusability.
IDE Support:
Ensure you’re using an IDE that supports Luau type checking, like Roblox Studio or Visual Studio Code with the Rojo extension.
Its VERY clear with the formatting, and the wording…
especially when you put a very detailed explanation with good formatting, punctuation, e.t.c.
And right after you put a poorly punctuated and short comment.
Don’t think AI will help you get solutions, most AIs aren’t smart enough to generate whole solutions for you.
Actually learn about the topic rather than asking AI, you will get a much more deep understanding of the topic. And you will be able to ACTUALLY help people.
Can you put --!strict at the top of the editor of each script and let me know what warnings you get? You can view the warnings by hovering over the underlined text (if they show up). As already mentioned, the issue is with how the type solver infers your class type with inheritence.
Hey! So I just started to play around with the different orders of things, and added more specific type checking and got a version that actually works. Here are all the scripts (Just so you know I changed up the names a bit to make it easier to work with in studio):
Module 1:
local Classy = {}
Classy.__index = Classy
function Classy:extend()
local Class = {}
Class.__index = Class
setmetatable(Class, {__index = self})
return Class
end
return Classy
Module 2:
local Classy = require(game:GetService("ReplicatedStorage").Classy)
export type AnimalClass = {
Name: string,
new: (Name: string) -> AnimalClass,
Speak: (self: AnimalClass) -> (),
}
local AnimalClass : AnimalClass = Classy:extend()
function AnimalClass.new(Name: string)
local Animal = setmetatable({}, AnimalClass)
Animal.Name = Name
return Animal
end
function AnimalClass:Speak()
print(self.Name)
end
return AnimalClass
The server script you can keep as normal and unchanged.
But how do I add extra functions to the export type, and is it possible to “stack” them when I extend another class from one already with an export type?