pub struct CompatChecker<'a, R: TypeResolver = NoopResolver> { /* private fields */ }Expand description
Compatibility checker that applies TypeScript’s unsound rules before delegating to the structural subtype engine.
This layer integrates with the “Lawyer” layer to apply nuanced rules
for any propagation.
Implementations§
Source§impl<'a> CompatChecker<'a, NoopResolver>
impl<'a> CompatChecker<'a, NoopResolver>
Sourcepub fn new(interner: &'a dyn TypeDatabase) -> Self
pub fn new(interner: &'a dyn TypeDatabase) -> Self
Create a new compatibility checker without a resolver.
Note: Callers should configure strict_function_types explicitly via set_strict_function_types()
Source§impl<'a, R: TypeResolver> CompatChecker<'a, R>
impl<'a, R: TypeResolver> CompatChecker<'a, R>
Sourcepub fn with_resolver(interner: &'a dyn TypeDatabase, resolver: &'a R) -> Self
pub fn with_resolver(interner: &'a dyn TypeDatabase, resolver: &'a R) -> Self
Create a new compatibility checker with a resolver.
Note: Callers should configure strict_function_types explicitly via set_strict_function_types()
Sourcepub fn set_query_db(&mut self, db: &'a dyn QueryDatabase)
pub fn set_query_db(&mut self, db: &'a dyn QueryDatabase)
Set the query database for Salsa-backed memoization.
Propagates to the internal SubtypeChecker.
Sourcepub const fn set_inheritance_graph(
&mut self,
graph: Option<&'a InheritanceGraph>,
)
pub const fn set_inheritance_graph( &mut self, graph: Option<&'a InheritanceGraph>, )
Set the inheritance graph for nominal class subtype checking.
Propagates to the internal SubtypeChecker.
Sourcepub fn set_strict_function_types(&mut self, strict: bool)
pub fn set_strict_function_types(&mut self, strict: bool)
Configure strict function parameter checking. See https://github.com/microsoft/TypeScript/issues/18654.
Sourcepub fn set_strict_null_checks(&mut self, strict: bool)
pub fn set_strict_null_checks(&mut self, strict: bool)
Configure strict null checks (legacy null/undefined assignability).
Sourcepub fn set_no_unchecked_indexed_access(&mut self, enabled: bool)
pub fn set_no_unchecked_indexed_access(&mut self, enabled: bool)
Configure unchecked indexed access (include undefined in T[K]).
Sourcepub fn set_exact_optional_property_types(&mut self, exact: bool)
pub fn set_exact_optional_property_types(&mut self, exact: bool)
Configure exact optional property types. See https://github.com/microsoft/TypeScript/issues/13195.
Sourcepub fn set_strict_subtype_checking(&mut self, strict: bool)
pub fn set_strict_subtype_checking(&mut self, strict: bool)
Configure strict mode for any propagation.
Configure strict subtype checking mode for lib.d.ts type checking.
When enabled, applies additional strictness rules that reject borderline cases allowed by TypeScript’s legacy behavior. This includes disabling method bivariance for soundness.
Sourcepub fn apply_flags(&mut self, flags: u16)
pub fn apply_flags(&mut self, flags: u16)
Apply compiler options from a bitmask flags value.
The flags correspond to RelationCacheKey bits:
- bit 0:
strict_null_checks - bit 1:
strict_function_types - bit 2:
exact_optional_property_types - bit 3:
no_unchecked_indexed_access - bit 4:
disable_method_bivariance(strict_subtype_checking) - bit 5:
allow_void_return - bit 6:
allow_bivariant_rest - bit 7:
allow_bivariant_param_count
This is used by QueryCache::is_assignable_to_with_flags to ensure
cached results respect the compiler configuration.
Sourcepub fn set_strict_any_propagation(&mut self, strict: bool)
pub fn set_strict_any_propagation(&mut self, strict: bool)
When strict mode is enabled, any does NOT silence structural mismatches.
This means the type checker will still report errors even when any is involved,
if there’s a real structural mismatch.
Sourcepub const fn lawyer(&self) -> &AnyPropagationRules
pub const fn lawyer(&self) -> &AnyPropagationRules
Get a reference to the lawyer layer for any propagation rules.
Sourcepub fn lawyer_mut(&mut self) -> &mut AnyPropagationRules
pub fn lawyer_mut(&mut self) -> &mut AnyPropagationRules
Get a mutable reference to the lawyer layer for any propagation rules.
Sourcepub fn apply_config(&mut self, config: &JudgeConfig)
pub fn apply_config(&mut self, config: &JudgeConfig)
Apply configuration from JudgeConfig.
This is used to configure the CompatChecker with settings from
the CompilerOptions (passed through JudgeConfig).
Sourcepub fn is_assignable(&mut self, source: TypeId, target: TypeId) -> bool
pub fn is_assignable(&mut self, source: TypeId, target: TypeId) -> bool
Check if source is assignable to target using TS compatibility rules.
pub fn is_assignable_strict(&mut self, source: TypeId, target: TypeId) -> bool
Sourcepub fn explain_failure(
&mut self,
source: TypeId,
target: TypeId,
) -> Option<SubtypeFailureReason>
pub fn explain_failure( &mut self, source: TypeId, target: TypeId, ) -> Option<SubtypeFailureReason>
Explain why source is not assignable to target using TS compatibility rules.
pub fn is_weak_union_violation(&self, source: TypeId, target: TypeId) -> bool
Source§impl<'a, R: TypeResolver> CompatChecker<'a, R>
impl<'a, R: TypeResolver> CompatChecker<'a, R>
Sourcepub fn is_assignable_with_overrides<P: AssignabilityOverrideProvider + ?Sized>(
&mut self,
source: TypeId,
target: TypeId,
overrides: &P,
) -> bool
pub fn is_assignable_with_overrides<P: AssignabilityOverrideProvider + ?Sized>( &mut self, source: TypeId, target: TypeId, overrides: &P, ) -> bool
Check if source is assignable to target using TS compatibility rules,
with checker-provided overrides for enums, abstract constructors, and accessibility.
This is the main entry point for assignability checking when checker context is available.
Sourcepub fn private_brand_assignability_override(
&self,
source: TypeId,
target: TypeId,
) -> Option<bool>
pub fn private_brand_assignability_override( &self, source: TypeId, target: TypeId, ) -> Option<bool>
Private brand assignability override. If both source and target types have private brands, they must match exactly. This implements nominal typing for classes with private fields.
Uses recursive structure to preserve Union/Intersection semantics:
- Union (A | B): OR logic - must satisfy at least one branch
- Intersection (A & B): AND logic - must satisfy all branches
Sourcepub fn enum_assignability_override(
&self,
source: TypeId,
target: TypeId,
) -> Option<bool>
pub fn enum_assignability_override( &self, source: TypeId, target: TypeId, ) -> Option<bool>
Enum member assignability override.
Implements nominal typing for enum members: EnumA.X is NOT assignable to EnumB even if values match.
TypeScript enum rules:
- Different enums with different
DefIdsare NOT assignable (nominal typing) - Numeric enums are bidirectionally assignable to number (Rule #7 - Open Numeric Enums)
- String enums are strictly nominal (string literals NOT assignable to string enums)
- Same enum members with different values are NOT assignable (EnumA.X != EnumA.Y)
- Unions containing enums: Source union assigned to target enum checks all members
Sourcepub fn are_types_identical_for_redeclaration(
&mut self,
a: TypeId,
b: TypeId,
) -> bool
pub fn are_types_identical_for_redeclaration( &mut self, a: TypeId, b: TypeId, ) -> bool
Checks if two types are compatible for variable redeclaration (TS2403).
This applies TypeScript’s nominal identity rules for enums and respects ‘any’ propagation. Used for checking if multiple variable declarations have compatible types.
§Examples
var x: number; var x: number→ truevar x: E.A; var x: E.A→ truevar x: E.A; var x: E.B→ falsevar x: E; var x: F→ false (different enums)var x: E; var x: number→ false
Trait Implementations§
Source§impl<'a, R: TypeResolver> AssignabilityChecker for CompatChecker<'a, R>
impl<'a, R: TypeResolver> AssignabilityChecker for CompatChecker<'a, R>
fn is_assignable_to(&mut self, source: TypeId, target: TypeId) -> bool
fn is_assignable_to_strict(&mut self, source: TypeId, target: TypeId) -> bool
Source§fn is_assignable_to_bivariant_callback(
&mut self,
source: TypeId,
target: TypeId,
) -> bool
fn is_assignable_to_bivariant_callback( &mut self, source: TypeId, target: TypeId, ) -> bool
Source§fn evaluate_type(&mut self, type_id: TypeId) -> TypeId
fn evaluate_type(&mut self, type_id: TypeId) -> TypeId
Func<T> must be expanded to their structural form (e.g., a Callable).
The default implementation returns the type unchanged (no resolver available).