pub enum Type {
Show 30 variants
Number,
NumberLiteral(LiteralF64),
BigInt,
BigIntLiteral(String),
String,
StringLiteral(String),
Uint8Array,
Boolean,
BooleanLiteral(bool),
Null,
Undefined,
Void,
Unknown,
Function {
params: Vec<Type>,
optional: usize,
ret: Box<Type>,
predicate: Option<Box<TypePredicate>>,
has_rest: bool,
},
Object {
fields: BTreeMap<String, ObjectField>,
index: Option<IndexSignature>,
},
Array(Box<Type>),
Tuple(TupleType),
Readonly(Box<Type>),
Error,
Never,
TypeVar(String),
GenericParam {
id: u32,
name: String,
},
Refined {
original: Box<Type>,
ty: Box<Type>,
},
InterfaceRef {
mangled: MangledName,
package: Package,
name: String,
args: Vec<Type>,
},
ClassRef {
mangled: MangledName,
package: Package,
name: String,
args: Vec<Type>,
},
NumberEnum {
mangled: MangledName,
package: Package,
name: String,
member: Option<EnumMember<LiteralF64>>,
},
StringEnum {
mangled: MangledName,
package: Package,
name: String,
member: Option<EnumMember<String>>,
},
Union(Vec<Type>),
Alias {
mangled: MangledName,
package: Package,
name: String,
args: Vec<Type>,
ty: Box<Type>,
},
AliasRef {
mangled: MangledName,
package: Package,
name: String,
args: Vec<Type>,
},
}Variants§
Number
NumberLiteral(LiteralF64)
No distinct runtime representation — codegen widens to f64 at every emission site.
BigInt
BigIntLiteral(String)
A bigint literal type: 123n, -1n. Holds the value in decimal, with a
leading - when negative, so each value has one spelling. Like the other
literal types it lowers exactly as its base, bigint.
String
StringLiteral(String)
Uint8Array
Boolean
BooleanLiteral(bool)
true or false. Like the other literal types it has no runtime
representation of its own: it lowers exactly as boolean. Type::union
folds true | false into boolean, which is what boolean means.
Null
Undefined
The single undefined value, distinct from language null and Wasm null.
Void
Unknown
Unlike TypeScript’s any, requires explicit narrowing before use.
Unknown | T collapses to Unknown.
Function
Fields
predicate: Option<Box<TypePredicate>>Boxed to break the Type → Function → TypePredicate → Type cycle. Guards are
assignable to plain functions but not vice versa.
Object
BTreeMap gives structural ==, deterministic iteration, and canonical field order for codegen.
Array(Box<Type>)
Tuple(TupleType)
Parser rejects empty tuples. Index access requires an integer literal; out-of-range and
non-literal indices are rejected at typecheck time. Lowers to (ref $Array) at runtime.
Readonly(Box<Type>)
readonly T[] (also spelled ReadonlyArray<T>) or readonly [A, B]. The inner
type is always a Type::Array or Type::Tuple: the wrapper only forbids
writes, so Type::peel strips it and every read path sees the plain array.
Write paths (index assignment, mutating methods) must ask
Type::is_readonly_array before peeling. Eq/Ord keep it distinct from the
mutable type because a readonly array is not assignable to a mutable one.
Error
Diagnostic already reported; downstream code must not emit cascading errors.
Never
No Wasm representation — never values never reach codegen.
TypeVar(String)
Signature-form generic parameter. Never appears in function bodies — body inference
replaces each TypeVar with a fresh GenericParam at body entry.
GenericParam
Body-internal generic placeholder. Identity by id — two GPs with different ids are
distinct even when they share a name, preventing collisions across nested generic scopes.
Refined
A generic value with a proven runtime shape. Member access and lowering
use ty; assignability also preserves the original generic identity.
InterfaceRef
args carries already-substituted type arguments; empty for non-generic interfaces.
mangled is the declaring symbol’s mangled name — the nominal identity (two
modules’ same-named interfaces have distinct mangled names). package/name are
kept for diagnostics and import-independent structural resolution (see Package);
they do not drive identity. mangled is listed first so derived Ord keys on it.
ClassRef
Nominal reference to a class declaration. Identity is mangled (two modules’
same-named classes are distinct); package/name are for diagnostics and
import-independent structural resolution, mirroring Type::InterfaceRef.
args instantiates the class’s type parameters; empty for a
non-generic class.
NumberEnum
Distinct from StringEnum so codegen knows the i32 representation without consulting the type namespace.
member narrows the enum to one member’s literal type, E.A, which is
what a member read has, as in TypeScript. It shares the enum’s runtime
representation; Type::widen_literal drops it back to the enum.
StringEnum
Union(Vec<Type>)
Canonical union: sorted, deduplicated, no nested unions, no Error members, always ≥2
members. Build only via Type::union.
Alias
Every pattern-match site must call Type::peel first; sole exception is
Display. Eq/Ord/Hash are nominal: Alias { "ID", Number } ≠
Number at the raw level. args carries already-substituted type arguments.
AliasRef
Lazy by-name reference to a type alias, used only at a
recursion back-edge — the inner Json in
type Json = number | string | Json[], or the Node in
type Node = { next: Node | null }. Unlike Type::Alias it
carries no inline body; the body lives in the type namespace and
is resolved by name on demand (mirroring Type::InterfaceRef).
This keeps a recursive alias a finite Type value — a cyclic
inline body would infinitely recurse the derived Eq/Ord and
Type::peel. peel does not expand it (it stops here, the
same as InterfaceRef); the few sites that need the alias’s
structure resolve it by name with cycle-safety.
Implementations§
Source§impl Type
impl Type
pub fn tuple(elements: Vec<Type>) -> Self
Sourcepub fn is_structural_object(&self) -> bool
pub fn is_structural_object(&self) -> bool
A receiver whose computed string keys use the object property carrier.
Sourcepub fn interface_ref(
package: Package,
name: impl Into<String>,
mangled: MangledName,
args: Vec<Type>,
) -> Type
pub fn interface_ref( package: Package, name: impl Into<String>, mangled: MangledName, args: Vec<Type>, ) -> Type
Build an Type::InterfaceRef. mangled is the declaring symbol’s mangled
name (its nominal identity) — pass the symbol’s own mangled_name, never a
value recomputed from package/name, so two construction sites for the same
type always agree.
Sourcepub fn class_ref(
package: Package,
name: impl Into<String>,
mangled: MangledName,
args: Vec<Type>,
) -> Type
pub fn class_ref( package: Package, name: impl Into<String>, mangled: MangledName, args: Vec<Type>, ) -> Type
Build a Type::ClassRef. mangled is the class symbol’s nominal identity;
pass the symbol’s own mangled_name, never one recomputed from package/name.
pub fn number_enum( package: Package, name: impl Into<String>, mangled: MangledName, ) -> Type
pub fn string_enum( package: Package, name: impl Into<String>, mangled: MangledName, ) -> Type
Sourcepub fn with_enum_member(
&self,
member_name: &str,
value: EnumValue,
member_count: usize,
) -> Type
pub fn with_enum_member( &self, member_name: &str, value: EnumValue, member_count: usize, ) -> Type
The member literal type E.A of the enum type self, which has
member_count members. self must be a NumberEnum holding a number
or a StringEnum holding a string. As in TypeScript, the one member of
an enum has the enum’s own type.
Sourcepub fn without_enum_member(&self) -> Type
pub fn without_enum_member(&self) -> Type
The enum a member literal type E.A belongs to; any other type unchanged.
Sourcepub fn is_literal_type(&self) -> bool
pub fn is_literal_type(&self) -> bool
Whether this is one literal type, what TypeScript calls a unit type:
1, "a", true, 1n or an enum member E.A.
Sourcepub fn is_enum_member(&self) -> bool
pub fn is_enum_member(&self) -> bool
Whether this is an enum member literal type E.A.
Sourcepub fn enum_member_name(&self) -> Option<(&MangledName, &str, usize)>
pub fn enum_member_name(&self) -> Option<(&MangledName, &str, usize)>
The enum, member name and member count of an enum member literal type E.A.
Sourcepub fn enum_member_value(&self) -> Option<EnumValue>
pub fn enum_member_value(&self) -> Option<EnumValue>
The value an enum member literal type E.A holds.
pub fn alias_ref( package: Package, name: impl Into<String>, mangled: MangledName, args: Vec<Type>, ) -> Type
pub fn alias_ty( package: Package, name: impl Into<String>, mangled: MangledName, args: Vec<Type>, ty: Box<Type>, ) -> Type
Sourcepub fn prelude_interface(name: impl Into<String>, args: Vec<Type>) -> Type
pub fn prelude_interface(name: impl Into<String>, args: Vec<Type>) -> Type
Convenience for a non-namespaced prelude interface (Error, Response, …):
the prelude registers these with mangled_name = prelude(name), so this is
the matching identity. Namespaced prelude types (Temporal.*) must instead
use Type::interface_ref with extend(prelude("Temporal"), local).
Sourcepub fn prelude_error_class() -> Type
pub fn prelude_error_class() -> Type
The built-in Error class reference — the type of throw/catch values
and the root of user error subclasses.
Sourcepub fn prelude_range_error_class() -> Type
pub fn prelude_range_error_class() -> Type
The built-in RangeError class reference — the host-implemented
Error subclass for out-of-range failures.
Sourcepub fn without_aliases(&self) -> &Type
pub fn without_aliases(&self) -> &Type
Remove display aliases while retaining generic guard identity.
pub fn peel(&self) -> &Type
Sourcepub fn peel_preserving_readonly(&self) -> &Type
pub fn peel_preserving_readonly(&self) -> &Type
peel, but stopping at a Type::Readonly wrapper, for
sites that carry a type onward and must not drop its readonly-ness.
Sourcepub fn is_readonly_array(&self) -> bool
pub fn is_readonly_array(&self) -> bool
Whether writes through a value of this type are forbidden because it is a
readonly array or tuple, looking through aliases and refinements.
Sourcepub fn rest_element(&self) -> Option<&Type>
pub fn rest_element(&self) -> Option<&Type>
The element type of a rest parameter’s array: T for T[] or
readonly T[]. Not peeled through aliases, since rest lowering matches the
parameter type as written.
Sourcepub fn rest_array_ignoring_readonly(&self) -> &Type
pub fn rest_array_ignoring_readonly(&self) -> &Type
A rest parameter’s type with any readonly removed. Each call packs a
fresh array for the rest, so whether the callee may write to it is the
callee’s own concern: two function types relate on their rest elements,
as in tsc.
Sourcepub fn is_array_like_union(&self) -> bool
pub fn is_array_like_union(&self) -> bool
Whether this is a union of only arrays and tuples, which share the $Array
representation.
Sourcepub fn array_like_union_element(&self) -> Option<Type>
pub fn array_like_union_element(&self) -> Option<Type>
The element of a union of arrays and tuples read as one array: any
member’s element. None for any other type. Only reads may go through
it; writing a member’s element through the joined type could store
another member’s element type.
Sourcepub fn string_or_array_union_arrays(&self) -> Option<Type>
pub fn string_or_array_union_arrays(&self) -> Option<Type>
The arrays and tuples of a union of strings with arrays or tuples, and
nothing else, as their own union. Such a union has no shared
representation, so each use tests typeof and takes the string’s or the
array’s path.
Sourcepub fn array_like_union_view(&self) -> Option<Type>
pub fn array_like_union_view(&self) -> Option<Type>
The array a union of arrays and tuples reads as: see
Self::array_like_union_element.
Sourcepub fn is_void(&self) -> bool
pub fn is_void(&self) -> bool
Whether this type is void, through any depth of alias.
void is the one type with no value slot at all, so a gate that tests
for it decides between “one Wasm result” and “none”. Every such gate —
in the typechecker and in codegen — must answer the same way for
type V = void as for void: a bare matches!(ty, Type::Void) hands an
aliased void a value slot that
SymbolTable::value_type
then refuses to lower. A typecheck gate must not start peeling ahead of
its codegen counterpart, which turns a clean diagnostic into a panic.
Sourcepub fn function_arity_fits(
actual: usize,
expected: usize,
has_rest: bool,
) -> bool
pub fn function_arity_fits( actual: usize, expected: usize, has_rest: bool, ) -> bool
Whether a function taking actual parameters can stand where one taking
expected is called. As in TypeScript, it may declare fewer and ignore
the rest of the arguments; a closure adapter drops them at runtime. Rest
functions keep an exact arity, since their packed array has a slot of its
own.
Sourcepub fn carries_void(&self) -> bool
pub fn carries_void(&self) -> bool
Whether a value of this type would need a void slot at runtime:
void itself, or a union that lists it.
Deliberately one level deep — it does not descend into a function’s
return type, where void is legitimate (() => void). Every gate that
refuses void in a value or comparison position wants this, not the
bare is_void. cond ? f() : 1 and a ?? f() are
plain void, so no expression builds the union form; a gate that asks
this still refuses one that did, rather than letting it reach codegen.
Sourcepub fn primitive_behavior(&self) -> &Type
pub fn primitive_behavior(&self) -> &Type
Primitive operations shared by enums and homogeneous literal unions, without widening their type identity or changing assignability.
Sourcepub fn is_bigint(&self) -> bool
pub fn is_bigint(&self) -> bool
Whether every value of this type is a bigint: bigint, a bigint literal
type, or a union or alias of those.
Sourcepub fn widen_literal(&self) -> Type
pub fn widen_literal(&self) -> Type
This type with literal types replaced by the primitive they are a literal of.
A literal type is only sound where the value cannot change, so inference keeps
it at a const binding and widens here at every position that is mutable or
whose type is inferred from its contents — a let binding, an array element,
an object-literal property, a generic argument. const a = 1 is 1, but
let b = a is number, matching TypeScript.
An enum member literal type E.A widens to its enum E, not to the
enum’s primitive: the enum is a nominal type whose identity its members
are checked against. Use primitive_behavior
for the primitive.
Sourcepub fn literal_base(&self) -> Option<Type>
pub fn literal_base(&self) -> Option<Type>
The primitive this literal type, or union of literals of one
primitive, is a literal of: number for 1 | 2, None for
1 | "a" or a type that is no literal.
Sourcepub fn is_string_shaped(&self) -> bool
pub fn is_string_shaped(&self) -> bool
Whether every part of this type is a string — a string, a
string-literal type, or a union of those.
The typechecker, the import collector, and codegen must agree on this
exactly: a shape accepted by one and not the others emits a $string
into an f64 slot, which fails Wasm validation rather than type
checking. Contrast contains_string, which
asks the any question.
Sourcepub fn contains_string(&self) -> bool
pub fn contains_string(&self) -> bool
Whether some part of this type is a string. Diagnostics-only: it is
what decides whether a rejected operand still deserves the “convert
first” help, so string | null gets it.
Sourcepub fn any_member(&self, leaf: &dyn Fn(&Type) -> bool) -> bool
pub fn any_member(&self, leaf: &dyn Fn(&Type) -> bool) -> bool
Whether any member, through unions, satisfies leaf, which sees peeled
types. Syntactic: an alias reference is a leaf, not expanded; the
typechecker’s any_resolved_member follows alias bodies through its
resolver.
Sourcepub fn all_members(&self, leaf: &dyn Fn(&Type) -> bool) -> bool
pub fn all_members(&self, leaf: &dyn Fn(&Type) -> bool) -> bool
Whether every member, through unions, satisfies leaf. Syntactic,
like Type::any_member.
Sourcepub fn spells_null(&self) -> bool
pub fn spells_null(&self) -> bool
Whether null is spelled among the members. Syntactic, unlike the
typechecker’s type_admits_null: unknown doesn’t count.
Sourcepub fn spells_undefined(&self) -> bool
pub fn spells_undefined(&self) -> bool
Whether undefined, or an erased void result, is spelled among the
members. unknown and type parameters don’t count.
Sourcepub fn stringifies_to_undefined(leaf: &Type) -> bool
pub fn stringifies_to_undefined(leaf: &Type) -> bool
Whether a value of the member type leaf has no JSON text at the
document root, so JSON.stringify returns undefined for it.
Objects and arrays holding such values still produce a document.
Sourcepub fn union(members: Vec<Type>) -> Type
pub fn union(members: Vec<Type>) -> Type
Normalizes to a flat member list that is unique by peeled type.
Both halves peel because a nominal key is unsound here: an alias whose
body is a union is a nested union in disguise, and every downstream
per-member probe (value_type’s nullability test, narrowing’s member
walk) reads it as one opaque member. Deduping nominally leaves
N | number as a two-member union that no operator is defined on.
The alias label a union displays therefore survives only where it is
still a single member: an alias of a union is replaced by its members,
and among duplicates the alias-labelled spelling wins regardless of
source order, so N | number and number | N both keep N.
peel stops at a recursive alias (it is a name, not a body), so a
recursive alias never dedups against its own expansion. Both spellings
lower the same way, so this costs a redundant member, not correctness.
Sourcepub fn interface_routing(&self) -> Option<(MangledName, &str, &str, Vec<Type>)>
pub fn interface_routing(&self) -> Option<(MangledName, &str, &str, Vec<Type>)>
For method dispatch. Erased generics route to Object. Aliases peel. Returns None
for function, void, null, and error. The first tuple element is the owning package
for diagnostics; the mangled name is the structural lookup key. Built-in
interfaces (Number, Array, Object, …) live in the prelude package.
Source§impl Type
impl Type
pub fn render_checked( &self, limits: RenderLimits, ) -> Result<RenderedText, RenderError>
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Type
impl<'de> Deserialize<'de> for Type
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for Type
Source§impl Ord for Type
impl Ord for Type
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
1.21.0 (const: unstable) · Source§fn min(self, other: Self) -> Selfwhere
Self: Sized,
fn min(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for Type
impl PartialOrd for Type
impl StructuralPartialEq for Type
Auto Trait Implementations§
impl Freeze for Type
impl RefUnwindSafe for Type
impl Send for Type
impl Sync for Type
impl Unpin for Type
impl UnsafeUnpin for Type
impl UnwindSafe for Type
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.