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 (no trailing ;), inside an
entity or at program scope:
entity Token {
type Amount = U256
type Timestamp = u64
}
After declaration, the alias can be used in place of the original type. The
two names are interchangeable: a U256 parameter or a literal can be
assigned to an Amount member and vice versa.
Usage
Aliases make member declarations, route signatures, and record fields more expressive:
entity Token {
type Amount = U256
record Transfer {
sender: address,
recipient: address,
value: Amount
}
routes {
mint(to: address, amount: Amount) => []
transfer(to: address, amount: Amount)
where m_balances[msg::sender] >= amount : throw 100
=> []
}
m_total_supply: Amount {
in mint(_, amount) => m_total_supply + amount
}
m_balances: HashMap<address, Amount> {
in mint(to, amount) => m_balances.insert(to, m_balances[to] + amount)
in transfer(to, amount) => m_balances
.insert(msg::sender, m_balances[msg::sender] - amount)
.insert(to, m_balances[to] + 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. Declare an alias at program scope (outside any entity) to share it between entities.
Aliases vs. Newtypes
Type aliases are transparent – two aliases of the same type are not distinguished. This means you cannot use aliases to prevent accidental mixing of conceptually different values:
type UserId = u64
type ProductId = u64
// Accepted: both names stand for u64.
pure fn as_product(user: UserId) -> ProductId {
user
}
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 }