Skip to main content

Overview

@class defines a named type that other annotations can use. Classes support inheritance, generic type parameters, access control, and field definitions.

Syntax

---@class ClassName
---@class ClassName : ParentClass
---@class ClassName : Parent1, Parent2
---@class (exact) ClassName
---@class (partial) ClassName
---@class ClassName<T>

Basic class

---@class Animal
---@field name string Animal name
---@field species string Species
local Animal = {}

function Animal:Speak()
    print(self.name .. " makes a sound")
end

Inheritance

Use : ParentClass to extend another class. The child class gets the parent’s fields and methods.
---@class Dog : Animal
---@field breed string Dog breed
local Dog = setmetatable({}, { __index = Animal })

function Dog:Fetch(item)
    -- inherits Animal fields: self.name, self.species ✅
end

Multiple inheritance

---@class Flyable
---@field maxAltitude number

---@class Swimmable
---@field maxDepth number

---@class Duck : Animal, Flyable, Swimmable
---@field featherColor string

Exact classes

Mark a class as (exact) to prevent dynamic field additions. GLuaLS can report a diagnostic when code assigns a field outside the class definition:
In GLuaLS, this annotation has no effect. GLuaLS treats all classes as partial by default and turns related diagnostics off. GLuaLS keeps it for EmmyLua compatibility.
---@class (exact) Point
---@field x number
---@field y number

local p = Point.new(1, 2)
p.z = 3 -- ❌ Error: cannot add field 'z' to exact type Point

Partial classes

(partial) extends an existing class without relisting all fields:
In GLuaLS, this annotation has no effect. GLuaLS treats all classes as partial by default and turns related diagnostics off. GLuaLS keeps it for EmmyLua compatibility.
-- In one file:
---@class Animal
---@field name string

-- In another file:
---@class (partial) Animal
---@field weight number  -- adds weight to Animal without losing name

Generic classes

Add type parameters with angle brackets. You can use type parameters in field types:
---@class Container<T>
---@field items T[]
---@field capacity number

---@type Container<string>
local stringContainer = { items = {}, capacity = 10 }
stringContainer.items[1] = "hello" -- ✅ typed as string

Field access control

Use access modifiers in @field:
Access modifiers are optional. They affect type checking only, not runtime behavior. GLuaLS checks them and can report diagnostics when code uses private or protected fields from the wrong place.
---@class MyClass
---@field public name string Accessible everywhere
---@field private m_id number Only accessible in class methods
---@field protected m_parent MyClass Accessible in subclasses
See @field for details.

Attaching a class to a local variable

When you place ---@class above a local statement, GLuaLS types that variable as an instance of the class:
---@class Player
local Player = {}
-- Player is now typed as "instance of Player class"
To type a constructor table instead, use @type:
local Player = {}
---@type Player
local ply = Player.new()