pub enum TypeGuard {
Typeof(TypeofKind),
Instanceof(TypeId),
LiteralEquality(TypeId),
NullishEquality,
Truthy,
Discriminant {
property_path: Vec<Atom>,
value_type: TypeId,
},
InProperty(Atom),
Predicate {
type_id: Option<TypeId>,
asserts: bool,
},
Array,
ArrayElementPredicate {
element_type: TypeId,
},
}Expand description
AST-agnostic representation of a type narrowing condition.
This enum represents various guards that can narrow a type, without
depending on AST nodes like NodeIndex or SyntaxKind.
§Examples
typeof x === "string" -> TypeGuard::Typeof(TypeofKind::String)
x instanceof MyClass -> TypeGuard::Instanceof(MyClass_type)
x === null -> TypeGuard::NullishEquality
x -> TypeGuard::Truthy
x.kind === "circle" -> TypeGuard::Discriminant { property: "kind", value: "circle" }Variants§
Typeof(TypeofKind)
typeof x === "typename"
Narrows a union to only members matching the typeof result.
For example, narrowing string | number with Typeof(TypeofKind::String) yields string.
Instanceof(TypeId)
x instanceof Class
Narrows to the class type or its subtypes.
LiteralEquality(TypeId)
x === literal or x !== literal
Narrows to exactly that literal type (for equality) or excludes it (for inequality).
NullishEquality
x == null or x != null (checks both null and undefined)
JavaScript/TypeScript treats == null as matching both null and undefined.
Truthy
x (truthiness check in a conditional)
Removes falsy types from a union: null, undefined, false, 0, "", NaN.
Discriminant
x.prop === literal or x.payload.type === "value" (Discriminated Union narrowing)
Narrows a union of object types based on a discriminant property.
§Examples
- Top-level:
{ kind: "A" } | { kind: "B" }withpath: ["kind"]yields{ kind: "A" } - Nested:
{ payload: { type: "user" } } | { payload: { type: "product" } }withpath: ["payload", "type"]yields{ payload: { type: "user" } }
Fields
InProperty(Atom)
prop in x
Narrows to types that have the specified property.
Predicate
x is T or asserts x is T (User-Defined Type Guard)
Narrows a type based on a user-defined type predicate function.
§Examples
function isString(x: any): x is string { ... }
function assertDefined(x: any): asserts x is Date { ... }
if (isString(x)) { x; // string }
assertDefined(x); x; // Datetype_id: Some(T): The type to narrow to (e.g.,stringorDate)type_id: None: Truthiness assertion (asserts x), behaves likeTruthyasserts: true: This is an assertion (throws if false), affects control flow
Array
Array.isArray(x)
Narrows a type to only array-like types (arrays, tuples, readonly arrays).
§Examples
function process(x: string[] | number | { length: number }) {
if (Array.isArray(x)) {
x; // string[] (not number or the object)
}
}This preserves element types - string[] | number[] stays as string[] | number[],
it doesn’t collapse to any[].
ArrayElementPredicate
array.every(predicate) where predicate has type predicate
Narrows an array’s element type based on a type predicate.
§Examples
const arr: (number | string)[] = ['aaa'];
const isString = (x: unknown): x is string => typeof x === 'string';
if (arr.every(isString)) {
arr; // string[] (element type narrowed from number | string to string)
}This only applies to arrays. For non-array types, the type is unchanged.