Menu
Coddy logo textTech

Optional Properties

Part of the Introduction To Luau section of Coddy's Lua journey — lesson 39 of 73.

Not every field is always present. In Lua, a missing table field simply reads as nil — which is flexible, but also how bugs like attempt to concatenate a nil value sneak in.

Luau lets a shape say this explicitly: add ? after a field's type to mark it optional:

type User = {
    name: string,   -- required
    email: string?, -- optional: string or nil
}

local alice: User = {name = "Alice", email = "alice@luau.dev"}
local bob: User = {name = "Bob"} -- ✓ fine, email is optional

You've met this before with variables: string? is shorthand for string | nil. The same idea now applies to individual fields of a shape.

Because an optional field might be nil, you must check before using it. The classic Lua pattern works, and in strict mode the checker narrows the type inside the branch:

if bob.email then
    print(`email: {bob.email}`) -- here email is a string
else
    print("no email on file")
end

Optional means "may be absent" — it does not mean "any type". If email exists, it must still be a string.

challenge icon

Challenge

Easy

Create a type alias named User with:

  • name of type string (required)
  • email of type string? (optional)

Create two users:

  • alice — name "Alice", email "alice@luau.dev"
  • bob — name "Bob", no email

Create a function printContact that takes a User. If the user has an email it prints [name] - [email]; otherwise it prints [name] - no email.

Then:

  1. call printContact(alice)
  2. call printContact(bob)
  3. print the result of comparing bob.email == nil

Try it yourself

-- Write code here
-- 1) define type User with an optional email field
-- 2) create alice (with email) and bob (without)
-- 3) write printContact with a nil check
-- 4) call it for both users, then print bob.email == nil
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Introduction To Luau