The one of feature is a selection type for choosing exactly one named identity.

It provides a simplified way to model enum-like cases. The shared selection type rules are defined in Selection Types.

Inferred Syntax

Day is one of (
	monday
	tuesday
	wednesday
	thursday
	friday
	saturday
	sunday
)

The inferred syntax signals that the entries provided are identities and their associated values should be auto-generated by the compiler. For example, the above is semantically equivalent to this:

Day is one of (
	monday = 1
	tuesday = 2
	wednesday = 3
	thursday = 4
	friday = 5
	saturday = 6
	sunday = 7
)

Inferred values start at 1.

Authors may mix explicit and inferred values. Missing values are inferred from the previous value.

Day is one of (
	monday = 1
	tuesday
	wednesday = 10
	thursday
)

In this example, tuesday infers to 2 and thursday infers to 11.

Aliases

Duplicate underlying values are allowed. Duplicate values create aliases for the same selected value.

HttpStatus is one of (
	ok = 200
	success = 200
	notFound = 404
)

Aliases compare equal because they have the same underlying value.

HttpStatus.ok == HttpStatus.success // true

Aliases remain distinct entries for access, iteration, documentation, and editor display.

Composition

One-ofs can be constructed from a series of others using spread syntax.

Weekday is one of (
	monday
	tuesday
	wednesday
	thursday
	friday
)

Weekend is one of (
	saturday
	sunday
)

Day is one of (
	...Weekday
	...Weekend
)
Weekday is one of (
	monday = 1
	tuesday = 2
	wednesday = 3
	thursday = 4
	friday = 5
)

Weekend is one of (
	saturday = 6
	sunday = 7
)

Day is one of (
	...Weekday
	...Weekend
)

Iteration

One-ofs can be iterated at the type level. The iteration uses a 2-value nameless destructing syntax where the first value is a string containing the name of the enumerated entry, and the second value is the value of the enumerated entry.

Iteration happens in declaration order. Duplicate underlying values are still yielded as separate entries, similar to Object.entries().

Day is one of (
	monday
	tuesday
	wednesday
	thursday
	friday
	saturday
	sunday
)

printWeekdays()
(
	Day each dayName, dayNumber (
		if (dayNumber < 6) (
			console.log(dayName)
		)
	)
)

If the values have inconsistent types, an is check is necessary before accessing the value:

Constants is one of (
	name = "bob"
	number = 12
)

iterate()
(
	Constants each name, value (
		if (value is string) (
			console.log("The value is the string: " + value)
		)
		else if (value is number) (
			console.log("The value is the number: ((value))")
		)
	)
)

Referencing Scope Values

Referencing scope-reachable values is permitted, as long as those values are constant and statically inferable.

letterA = "a"
letterB = "b"
letterC = "c"

Letters is one of (
	a = letterA
	b = letterB
	c = letterC
)

Structural Compatibility

Entry names are part of one of structural compatibility.

A is one of (
	name = "bob"
	number = 12
)

B is one of (
	name = "bob"
	number = 12
	flag = true
)

A has the structure { name is "bob", number is 12 }.

B has the structure { name is "bob", number is 12, flag is true }.

B is compatible with A. A is not compatible with B.

Spread Syntax

one-of blocks support embedding via the spread syntax.

Weekday is one of (
	monday
	tuesday
	wednesday
	thursday
	friday
)

Weekend is one of (
	saturday
	sunday
)

Day is one of (
	...Weekday
	...Weekend
)

Direction is one of (
	up
	down
	left
	right
)

Position is one of (
	...Direction
	center
)

All Valid Value Types

One-ofs can use any compile-time-computable value from the primitive list. Arrays and anonymous objects are also valid when their values are compile-time computable.

Things is one of (
	letter = "a"
	digit = 1
	bool = true
	array = [1, 2, 3]
	object = {
		property1 = "value1"
		property2 = "value2"
	}
)