Unions
Unions define a type that must be exactly one of several possible variants. There are two types of unions:
- Union expressions
- Named unions
Union expressions
Section titled “Union expressions”Unnamed unions, or union expressions, can be declared by combining the variants using the | operator.
alias Breed = Beagle | GermanShepherd | GoldenRetriever;In this example, Breed can be either a Beagle, a GermanShepherd, or a GoldenRetriever.
Named unions
Section titled “Named unions”Named unions allow you to assign a name to the union and provide explicit variant references. Named unions are somewhat similar to enums, but instead of having string or numeric values, they use record models.
A named union can be declared with the union keyword. Its name must be an identifier.
union Breed { beagle: Beagle, shepherd: GermanShepherd, retriever: GoldenRetriever,}The above example is equivalent to the Breed alias mentioned earlier, with the difference that emitters can recognize Breed as a named entity and also identify the beagle, shepherd, and retriever names for the options. This format also allows the application of decorators to each of the options.
Keyword unions in expression position
Section titled “Keyword unions in expression position”Declaration expressions are an experimental TypeSpec feature. Using a model, enum, union, or scalar declaration in expression position yields an experimental-feature warning. Enable them without the warning by adding declaration-expressions to the features list in your tspconfig.yaml:
kind: projectfeatures: - declaration-expressionsThe union keyword can also be used anywhere a type expression is expected — for example as an alias value, a property type, a decorator or template argument, or a tuple element. Unlike a union expression built with the | operator, the keyword form can carry a name and named variants.
model Pet { // anonymous keyword union in expression position breed: union { Beagle, GermanShepherd, };
// named keyword union in expression position size: union Size { small: "S", medium: "M", large: "L", };}A keyword union used in expression position is marked as an expression and is not registered in the enclosing namespace, even when it is given a name. The name is kept on the resulting type for display purposes only — it cannot be referenced elsewhere.
Unlike the | operator, a keyword union used as an operand is not flattened into the surrounding union. For example, union { "a", "b" } | "c" produces a union of the nested union { "a", "b" } and "c", preserving the named variants.
You can apply decorators and doc comments to the declaration inline, and augment it through a navigation reference such as ::type.