Syntax
--!strict
type Result = { value: number, valid: boolean }Examples
Describe a function boundary
Standalone Luau or a Script in ServerScriptService. Script Analysis rejects a string passed to double. The annotation does not convert "6" into 6.
--!strict
local function double(value: number): number
return value * 2
end
local result = double(6)
print(result) -- 12Refine an unknown value
A runtime type check narrows unknown before arithmetic. Try passing a string and then 5; the first returns nil and the second returns 10.
--!strict
local function doubleIfNumber(value: unknown): number?
if type(value) ~= "number" then
return nil
end
return value * 2
end
print(doubleIfNumber("5"))
print(doubleIfNumber(5))Best practices
- Add --!strict at the start of a file and fix the warnings it exposes rather than silencing them with any.
- Use unknown for untrusted values until a runtime check establishes their shape.
- A type assertion (::) changes what the checker believes; it does not sanitize data or change its runtime value.
At a glance
- Purpose
- Typed scripting and Roblox development
- File extension
- .luau
- Runs in
- Luau host; Roblox engine examples require Roblox Studio
- Usually used with
- Roblox APIs and Studio
Specifications & further reading
Related Luau documentation
Functions, optional arguments and returns
Functions group a calculation or action behind a named boundary. Optional types allow nil; they do not supply defaults. Return tuples and variadic arguments are useful when the number of values matters, but named record results are often easier to extend.Tables, arrays and dictionaries
A Luau table can hold a sequence, a dictionary or a record. A sequence uses consecutive integer keys starting at one; named fields describe a record. Type annotations describe the intended shape to the checker, but do not copy tables or validate incoming data at runtime.Server authority, validation and rate limits
A valid-looking remote call can still be an impossible game action. Validate both the shape of a request and whether the sender may perform it now. This example lets a nearby living player request a visual switch; it does not trust a client position, target Instance or reward.Luau and Roblox scripting
Start with Luau values and functions, then use Roblox Studio to connect that code to players, Instances and events. Luau is the language; Roblox supplies the game engine APIs. Codectionary supports editing and highlighting, while these Roblox examples run in Studio.
Functions group a calculation or action behind a named boundary. Optional types allow nil; they do not supply defaults. Return tuples and variadic arguments are useful when the number of values matters, but named record results are often easier to extend.Tables, arrays and dictionaries
A Luau table can hold a sequence, a dictionary or a record. A sequence uses consecutive integer keys starting at one; named fields describe a record. Type annotations describe the intended shape to the checker, but do not copy tables or validate incoming data at runtime.Server authority, validation and rate limits
A valid-looking remote call can still be an impossible game action. Validate both the shape of a request and whether the sender may perform it now. This example lets a nearby living player request a visual switch; it does not trust a client position, target Instance or reward.Luau and Roblox scripting
Start with Luau values and functions, then use Roblox Studio to connect that code to players, Instances and events. Luau is the language; Roblox supplies the game engine APIs. Codectionary supports editing and highlighting, while these Roblox examples run in Studio.