2.17. Type Aliases

Type aliases allow you to give a new name to an existing type. This improves code readability and makes it easier to work with complex type declarations. Aliases are fully interchangeable with the types they refer to — they do not create new types.

2.17.1. typedef Declaration

A type alias is declared with the typedef keyword:

typedef Vec3 = float3
typedef StringArray = array<string>
typedef Callback = function<(x:int; y:int):bool>

Once defined, the alias can be used anywhere a type is expected:

var position : Vec3
var names : StringArray
var cb : Callback

Aliases can refer to complex types, including tables, arrays, tuples, variants, blocks, and lambdas:

typedef IntPair = tuple<int; int>
typedef Registry = table<string; array<int>>
typedef Transform = block<(pos:float3; vel:float3):float3>

2.17.2. Publicity

Type aliases can be public or private:

typedef public  Vec3 = float3       // visible to other modules
typedef private Internal = int      // only visible within this module

If no publicity is specified, the alias inherits the module’s default publicity (i.e., in public modules aliases are public, and in private modules they are private).

2.17.3. Shorthand Type Alias Syntax

Several composite types support a shorthand declaration syntax that creates a named type alias.

2.17.3.1. Tuple Aliases

Instead of writing a typedef for a tuple, you can use the tuple keyword directly:

tuple Vertex {
    position : float3
    normal   : float3
    uv       : float2
}

This is equivalent to:

typedef Vertex = tuple<position:float3; normal:float3; uv:float2>

(see Tuples).

2.17.3.2. Variant Aliases

Variants support a similar shorthand:

variant Value {
    i : int
    f : float
    s : string
}

This is equivalent to:

typedef Value = variant<i:int; f:float; s:string>

(see Variants).

2.17.3.3. Bitfield Aliases

Bitfields also support the shorthand syntax:

bitfield Permissions {
    read
    write
    execute
}

This is equivalent to:

typedef Permissions = bitfield<read; write; execute>

Bitfield aliases can specify a storage type:

bitfield SmallFlags : uint8 {
    active
    visible
}

(see Bitfields).

2.17.4. Local Type Aliases

Type aliases can be declared inside function bodies:

def process {
    typedef Entry = tuple<string; int>
    var data : Entry
    data = ("hello", 42)
}

Local type aliases are scoped to the enclosing block and are not visible outside it.

Type aliases can also be declared inside structure or class bodies:

struct Container {
    typedef Element = int
    data : array<Element>
}

2.17.5. Generic Type Aliases (auto)

In generic functions, the auto(Name) syntax creates inferred type aliases. These are resolved during function instantiation based on the actual argument types:

def first_element(a : array<auto(ElementType)>) : ElementType {
    return a[0]
}

let x = first_element([1, 2, 3])    // ElementType is inferred as int, returns int

Named auto aliases can be reused across multiple arguments to enforce type relationships:

def add_to_array(var arr : array<auto(T)>; value : T) {
    arr |> push(value)
}

(see Generic Programming).

2.17.6. Type Aliases with typedecl

The typedecl expression can be used inside generic functions to create types based on the type of an expression:

def make_table(key : auto(K)) {
    var result : table<typedecl(key); string>
    return <- result
}

Here the key type of the table is inferred from the type of the key argument.

(see Generic Programming).

See also

Datatypes for the built-in types that can be aliased, Tuples for tuple alias syntax, Variants for variant alias syntax, Bitfields for bitfield alias syntax.