@tabooharmony/roblox-luau-types

Use for Luau annotations, generics, unions, narrowing, strictness, sealed tables, module type exports, or typed metatables.

View in AI SkillSafe app
0 downloads
0 stars
0 demos
SKILL.md
nameroblox-luau-types
descriptionUse for Luau annotations, generics, unions, narrowing, strictness, sealed tables, module type exports, or typed metatables.
last_reviewed2026-08-21
sourceshttps://luau-lang.org/typecheck, https://raw.githubusercontent.com/Roblox/creator-docs/main/content/en-us/luau/type-checking.md

Luau Type System

When to Load

Load for Luau type system work: annotations, generics, union types, type narrowing, sealed/unsealed tables, strictness modes (--!strict vs --!nonstrict), module type exports, and metatable-backed object typing. For syntax questions, use roblox-luau-core. For OOP/async/modules, use roblox-luau-patterns.

Quick Reference

Strictness: Use --!strict for maintained code, --!nonstrict while transitioning, and --!nocheck only for legacy/generated code. Project settings and directives select the mode; do not assume one global default.

Inference philosophy: Infer first, annotate boundaries (params, returns, exports). Don't annotate every local. Noise hides signal.

Sealed vs unsealed tables:

local t = {}          -- unsealed: can add fields
t.x = 1               -- OK

local t: {x: number} = {x=1}  -- sealed: no new fields
t.y = 2               -- ERROR

Build tables fully before annotating. Passing/returning seals them.

Unions & tagged unions:

local id: string | number = "abc"
type State<T> = {kind:"loading"} | {kind:"ready", value:T} | {kind:"fail", msg:string}
-- Discriminate: if state.kind == "ready" then state.value is narrowed

Narrowing:

if typeof(value) == "string" then
    print(string.upper(value)) -- primitive narrowing
end
if instance:IsA("BasePart") then
    print(instance.Position) -- Instance narrowing
end
assert(optionalValue, "missing") -- non-nil narrowing

Generics: Use when input→output type matters. function first<T>(list: {T}): T?. Generic aliases: type Result<T> = {success: boolean, value: T?}. Never replace with any.

Type exports: export type Foo = {...} at module boundary. Consumers use require + Types.Foo.

Object typing: export type Counter = typeof(setmetatable({} :: CounterData, Counter)) for precise self.

Casts (::): Precision tool to narrow overly generic inference, never to hide errors.

Write types you can trust: annotations are contracts for the compiler, not proof of runtime validity. Trust boundaries (remotes, DataStores, HttpService, attributes) still get runtime checks even when everything is annotated; inside a trusted boundary, let types carry the load instead of re-checking every call.

Key mistakes: Unsealed any propagation in nonstrict, sealing tables too early, unions without discriminants, annotating every local.

Full reference: see references/full.md

Embed badges

Add these to your README to show the skill's verification status.

SkillSafe verified badge
Verified badge
[![SkillSafe verified badge](https://api.skillsafe.ai/v1/badge/@tabooharmony/roblox-luau-types/verified)](https://skillsafe.ai/skill/@tabooharmony/roblox-luau-types/)
Installs badge
Installs badge
[![Installs badge](https://api.skillsafe.ai/v1/badge/@tabooharmony/roblox-luau-types/installs)](https://skillsafe.ai/skill/@tabooharmony/roblox-luau-types/)
Scan badge
Scan badge
[![Scan badge](https://api.skillsafe.ai/v1/badge/@tabooharmony/roblox-luau-types/scan)](https://skillsafe.ai/skill/@tabooharmony/roblox-luau-types/)
Eval pass rate badge
Eval pass rate
[![Eval pass rate badge](https://api.skillsafe.ai/v1/badge/@tabooharmony/roblox-luau-types/eval)](https://skillsafe.ai/skill/@tabooharmony/roblox-luau-types/)