Type Assertions
Part of the Introduction To Luau section of Coddy's Lua journey. Lesson 74 of 80.
You already used :: once, in the enums chapter, to treat io.read() as a Direction. This lesson looks at it properly.
Sometimes you know more about a value than Luau's type checker does: a value typed any that you know is really a user record, for example. A type assertion (also called a cast) lets you tell the checker "trust me, treat this value as this type". Luau's cast operator is :::
type User = {id: number, username: string}
local raw: any = {id = 42, username = "alice_dev"}
local user = raw :: User
print(user.username) -- the checker now knows the fieldsA cast changes only what the type checker believes. It does nothing at runtime. It never converts a value: "5" :: any is still the string "5", not the number 5 (use tonumber for real conversion). And it never validates: if you assert the wrong type, the cast itself won't error. Your code will simply misbehave later, when it touches fields that aren't there.
When to use it: when a value arrives as any (or a broad union) and you genuinely know its shape. When not to: to silence a type error you don't understand: the error is usually telling you about a real bug, and casting it away just hides it. Prefer real checks (like the typeof guards in the next lesson) when you can verify at runtime.
Challenge
EasyRead a record that arrives typed any.
- Write
type User = {id: number, username: string, isActive: boolean}. - Write
local function describeUser(data: any): stringthat casts withlocal user = data :: Userand returns`User {user.id}: {user.username} (Active: {user.isActive})`. - Print
describeUser(rawUser2).
Press Run Code: the output shows User 15: bob_admin (Active: false).
Try it yourself
-- Raw records from outside the program: typed any
local rawUser1: any = {id = 7, username = "nina_dev", isActive = true}
local rawUser2: any = {id = 15, username = "bob_admin", isActive = false}
-- 1) type User = {...}
-- 2) describeUser(data: any): string, casting with ::
-- 3) print describeUser(rawUser2)
All lessons in Introduction To Luau
1Getting Started with Luau
What Is Luau?Why Use Luau?Your First Luau CodeType Checking & Error ModesRecap: Introduction to Luau4Working with Functions
Typing Params & Return ValuesTyping Anonymous FunctionsFunctions Returning NothingOptional ParametersDefault Parameter ValuesDefaults for BooleansVariadic FunctionsDefining Function TypesRecap: Typed Functions2Core Types
Number, String and BooleanThe 'any' Type: Escape HatchThe 'unknown' TypeNil & Optional TypesType Inference in ActionExplicit Type AnnotationsRecap: Core Types Practice5Aliases, Unions, Intersections
Type Aliases for PrimitivesUnion TypesWorking with Union TypesLiteral TypesIntersection TypesCombining Type AliasesRecap: Advanced Type Combos8Enums, the Luau Way
The Enum Pattern in LuauNumeric Enums with TablesString Enums as UnionsUsing Literal Union EnumsFreezing Constant TablesRecap: Enums, the Luau Way11Advanced Topics
Type AssertionsType Guards With typeofThe never TypeNil Safety In Strict ModeIndex SignaturesRecap: Config Value TypesRecap: Fine-Tuning Types3Typed Tables: Arrays & Maps
Typed ArraysAdding and Reading ElementsWhat is a Map Type?Declaring and Accessing MapsIterating TablesMixed-Shape TablesReading a GridBuilding a Gridtable.unpackRecap: Arrays and MapsPractice on your own: Online Luau compiler