Nominal types
type tokenId is uint declares a new type that is stored and encoded as a uint, but that the type checker keeps apart from uint and from every other type over uint.
nominal-types.lithe
(* `type x is T` makes a new type with T's representation. It does not mix with T,
or with other types over T, without an explicit conversion. *)
import "std/evm";
type BasisPoints is uint16;
type TokenId is uint;
type OrderId is bytes32;
storage is record {
fee : BasisPoints;
owners : map(TokenId, address);
}
external function setFee(const fee : BasisPoints) is {
storage.fee := fee;
}
external function claim(const id : TokenId) is {
storage.owners[id] := Evm.sender();
}
(* Convert out with the underlying type's name, and in with the new type's name. *)
external view function feeOn(const amount : uint) : uint is
amount * uint(uint16(storage.fee)) / 10_000
external pure function next(const id : TokenId) : TokenId is
TokenId(uint(id) + 1)Binding a raw uint to a tokenId is a compile error:
initializer type does not match its annotationInteger literals take on nominal types directly: const fee : BasisPoints := 500;.

