Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Type Aliases

Type aliases introduce a new name for an existing type. They improve code readability by giving domain-specific names to generic or primitive types without changing the underlying representation.

Syntax

A type alias is declared with the type keyword inside an entity:

entity Token {
    type Amount = U256;
    type AccountId = address;
    type Timestamp = u64;
}

After declaration, the alias can be used anywhere the original type is expected. The two names are fully interchangeable – no conversion is needed.

Usage

Aliases make member declarations, route signatures, and record fields more expressive:

entity Token {
    type Amount = U256;
    type AccountId = address;

    record Transfer {
        from: AccountId,
        to: AccountId,
        value: Amount
    }

    routes {
        transfer(to: AccountId, amount: Amount)
            where m_balances[msg::sender] >= amount : throw 100
        => []
    }

    m_total_supply: Amount {
        in mint(_, amount) => m_total_supply + amount
    }

    m_balances: HashMap<AccountId, Amount> {
        in transfer(to, amount) => {
            let from_bal = m_balances[msg::sender];
            let to_bal = m_balances.get(to).unwrap_or(0);
            m_balances
                .set(msg::sender, from_bal - amount)
                .set(to, to_bal + amount)
        }
    }
}

Aliases for Complex Types

Aliases are particularly valuable when the underlying type is verbose:

type Approvals = HashMap<address, HashMap<address, U256>>;
type Voters = Vec<address>;
type PriceOracle = Address<Oracle>;

Without aliases, these types would need to be repeated in full wherever they appear, making the code harder to read and maintain.

Scope

Type aliases declared inside an entity are scoped to that entity. They are not visible in other entities within the same file. If two entities need the same alias, each must declare its own.

Aliases vs. Newtypes

Type aliases are transparent – the compiler treats the alias and the original type as identical. This means you cannot use aliases to prevent accidental mixing of conceptually different values:

type UserId = u64;
type ProductId = u64;

// The compiler allows this because both are u64:
let user: UserId = 1;
let product: ProductId = user; // no error

If you need distinct types that the compiler will not conflate, consider using single-field records instead:

record UserId { value: u64 }
record ProductId { value: u64 }