Type aliases
A type alias introduces a new name for an existing type. It is not a
new type; AccountId and String are interchangeable at every level.
type AccountId = Stringtype Price = Decimaltype Pair = #(Int, Int)Transparent, not nominal
Section titled “Transparent, not nominal”Aliases are transparent: the compiler treats AccountId and
String as the same type. A function that takes String accepts an
AccountId, and vice versa.
fn greet_by_id(id: AccountId): String { "hello, ${id}" }
let s: String = "005000000000001"debug greet_by_id(s) // OK: AccountId is just StringIf you want a type that is incompatible with its underlying type at the API boundary, use an opaque type instead. Opaque types are nominal: the compiler keeps them distinct.
Good uses
Section titled “Good uses”-
Naming intent at the call site.
Id,AccountId,CaseIdall aliasString, but the name at the call site tells the reader what the caller expects. -
Shortening long generic types.
type DmlResult<T> = Result<T, DmlError>fn insert(acc: Account): DmlResult<Id> { ... } -
Giving function types a name. For function-valued parameters and fields, a function type alias reads better than the inline form. See function type aliases for the specific syntax.
No generic aliases without a parameter
Section titled “No generic aliases without a parameter”type AccountId = String is fine. type Box = List (partial
application) is not; aliases do not carry type parameters unless the
alias itself is parameterized:
type Box<T> = List<T> // OK: both sides take one parameter
fn empty<T>(): Box<T> { [] }Codegen
Section titled “Codegen”Aliases have no representation in generated Apex. They are
resolved during type-checking and disappear in the emitted code;
AccountId in Vertex becomes String in Apex, not a wrapper class.