Associated Types and Constants Associated types and constants contribute static members to a type that can be reused within the type and its implementors but do not need to be exposed to every single caller. Both associated types and constants also work in abstract types, and as they are associated with the type directly, they do not occupy any instance space on the type. All statically known types and constants share the same static evaluation logic, and thus associated types and constants also mix with generic parameters, conditional types, decorators, and so on. Types import { IteratorResult } from "destack:iter"; newtype interface Collection { type Item; type Return = void; next(): IteratorResult; } declare function collect(iter: I): I.Item[]; Associated types are type aliases scoped to some struct, class, or interface and can also reference the owner's generic parameters. interface BufferPool { type Buffer; type Error; acquire(count: usize): Result, this.Error>; release(buffer: this.Buffer): void; } Associated types can have their own generic parameters with the same generic parameter forms as ordinary declarations, including type parameters and const parameters (these are generic associated types, often called GATs). interface Storage { type Handle; type Page; } Constants In addition to associated types, nominal type declarations also support associated constant members as static compile-time values. Like static members, const members require no instance storage, but unlike static members, they are evaluated during compilation. interface RegisterBlock { const Width: uint; read(): [uint8; this.Width]; write(bytes: &[uint8; this.Width]): void; } Associated members participate in the same static evaluation / inference world, and so associated members can express dependent types and values that are dependent on others (including inferred!). interface Matrix { const Width: uint = Row extends string ? 8 : 4; type Bytes = [uint8; this.Width]; } Refinements Associated members (both types and constants) can be refined explicitly at application sites whenever an erased or constrained value needs a concrete associated type with type Name = T for types and const Name = value for constants. declare function readBlock>(block: T): [uint8; 16];