Codectionary / Developer documentation / Luau

Inference, annotations and strict mode

Luau can infer types from expressions, while annotations document the boundary of a function or record. Strict mode reports more incomplete assumptions. Static checks help authors; runtime checks still protect values received from players or saved storage.

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) -- 12

Refine 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