Ternaries

Ternaries use the same syntax and basic behavior as TypeScript.

label = enabled ? "Enabled" : "Disabled"

The format is:

<condition> ? <true-expression> : <false-expression>

A ternary is an expression. It produces the value of the true arm when the condition passes, and the value of the false arm otherwise.

Use ternaries for simple two-arm expression selection. Use if for statement control flow, and use matches for multi-arm expression selection.

Condition Types

A ternary condition follows the same rules as an if condition. It must be either:

Ternaries do not use TypeScript or JavaScript truthiness. Strings, numbers, arrays, objects, and other non-boolean values are not accepted as conditions merely because they could be interpreted as true or false.

label = count ? "Non-zero" : "Zero"
// Invalid: numbers are not coerced to boolean

label = count !== 0 ? "Non-zero" : "Zero"
// Valid

The same rule applies to strings and collections. Use explicit checks.

label = name !== "" ? name : "Anonymous"

status = items.length !== 0 ? "Has items" : "Empty"

Nullable Conditions

Nullable values are allowed directly in condition position. The condition checks whether the condition expression itself is not null.

displayName = user ? user.name : "Anonymous"

The true arm can use the non-null type.

user is User or null

displayName = user ? user.name : "Anonymous"

A non-nullable value is not allowed directly in condition position just because it contains nullable fields.

label = profile ? "Has profile" : "No profile"
// Invalid when profile itself is not nullable

label = profile.photo ? "Has photo" : "No photo"
// Valid when profile.photo is nullable

Nullable values keep their type when assigned to a local. The local can then be checked directly.

photo = profile.photo

label = photo ? "Has photo" : "No photo"

Nullable booleans follow the same rule as conditionals: false is still a boolean value, not null.

enabled is boolean or null

label = enabled ? "Enabled" : "Disabled or unset"

Use an explicit comparison when the distinction matters.

label = enabled !== null ? "Set" : "Unset"

Arm Types

The result type of a ternary is the shared type of its two arms.

label = enabled ? "Enabled" : "Disabled"
// label is string

When the two arms produce different types, the result is their union or common supertype.

value = useName ? name : count
// value is string or the type of count