1use crate::ObjectLiteralBuilder;
7use crate::def::DefId;
8use crate::intern::TypeInterner;
9use crate::narrowing;
10use crate::objects::element_access::{ElementAccessEvaluator, ElementAccessResult};
11use crate::relations::subtype::TypeResolver;
12use crate::type_factory::TypeFactory;
13use crate::types::{
14 CallableShape, CallableShapeId, ConditionalType, ConditionalTypeId, FunctionShape,
15 FunctionShapeId, IndexInfo, IntrinsicKind, MappedType, MappedTypeId, ObjectFlags, ObjectShape,
16 ObjectShapeId, PropertyInfo, PropertyLookup, RelationCacheKey, StringIntrinsicKind, SymbolRef,
17 TemplateLiteralId, TemplateSpan, TupleElement, TupleListId, TypeApplication, TypeApplicationId,
18 TypeData, TypeId, TypeListId, TypeParamInfo, Variance,
19};
20use std::sync::Arc;
21use tsz_binder::SymbolId;
22use tsz_common::interner::Atom;
23
24pub trait TypeDatabase {
29 fn intern(&self, key: TypeData) -> TypeId;
30 fn lookup(&self, id: TypeId) -> Option<TypeData>;
31 fn intern_string(&self, s: &str) -> Atom;
32 fn resolve_atom(&self, atom: Atom) -> String;
33 fn resolve_atom_ref(&self, atom: Atom) -> Arc<str>;
34 fn type_list(&self, id: TypeListId) -> Arc<[TypeId]>;
35 fn tuple_list(&self, id: TupleListId) -> Arc<[TupleElement]>;
36 fn template_list(&self, id: TemplateLiteralId) -> Arc<[TemplateSpan]>;
37 fn object_shape(&self, id: ObjectShapeId) -> Arc<ObjectShape>;
38 fn object_property_index(&self, shape_id: ObjectShapeId, name: Atom) -> PropertyLookup;
39 fn function_shape(&self, id: FunctionShapeId) -> Arc<FunctionShape>;
40 fn callable_shape(&self, id: CallableShapeId) -> Arc<CallableShape>;
41 fn conditional_type(&self, id: ConditionalTypeId) -> Arc<ConditionalType>;
42 fn mapped_type(&self, id: MappedTypeId) -> Arc<MappedType>;
43 fn type_application(&self, id: TypeApplicationId) -> Arc<TypeApplication>;
44
45 fn literal_string(&self, value: &str) -> TypeId;
46 fn literal_number(&self, value: f64) -> TypeId;
47 fn literal_boolean(&self, value: bool) -> TypeId;
48 fn literal_bigint(&self, value: &str) -> TypeId;
49 fn literal_bigint_with_sign(&self, negative: bool, digits: &str) -> TypeId;
50
51 fn union(&self, members: Vec<TypeId>) -> TypeId;
52 fn union_from_sorted_vec(&self, flat: Vec<TypeId>) -> TypeId;
53 fn union2(&self, left: TypeId, right: TypeId) -> TypeId;
54 fn union3(&self, first: TypeId, second: TypeId, third: TypeId) -> TypeId;
55 fn intersection(&self, members: Vec<TypeId>) -> TypeId;
56 fn intersection2(&self, left: TypeId, right: TypeId) -> TypeId;
57 fn intersect_types_raw2(&self, left: TypeId, right: TypeId) -> TypeId;
59 fn array(&self, element: TypeId) -> TypeId;
60 fn tuple(&self, elements: Vec<TupleElement>) -> TypeId;
61 fn object(&self, properties: Vec<PropertyInfo>) -> TypeId;
62 fn object_with_flags(&self, properties: Vec<PropertyInfo>, flags: ObjectFlags) -> TypeId;
63 fn object_with_flags_and_symbol(
64 &self,
65 properties: Vec<PropertyInfo>,
66 flags: ObjectFlags,
67 symbol: Option<SymbolId>,
68 ) -> TypeId;
69 fn object_fresh(&self, properties: Vec<PropertyInfo>) -> TypeId {
70 self.object_with_flags(properties, ObjectFlags::FRESH_LITERAL)
71 }
72 fn object_with_index(&self, shape: ObjectShape) -> TypeId;
73 fn function(&self, shape: FunctionShape) -> TypeId;
74 fn callable(&self, shape: CallableShape) -> TypeId;
75 fn template_literal(&self, spans: Vec<TemplateSpan>) -> TypeId;
76 fn conditional(&self, conditional: ConditionalType) -> TypeId;
77 fn mapped(&self, mapped: MappedType) -> TypeId;
78 fn reference(&self, symbol: SymbolRef) -> TypeId;
79 fn lazy(&self, def_id: DefId) -> TypeId;
80 fn bound_parameter(&self, index: u32) -> TypeId;
81 fn recursive(&self, depth: u32) -> TypeId;
82 fn type_param(&self, info: TypeParamInfo) -> TypeId;
83 fn type_query(&self, symbol: SymbolRef) -> TypeId;
84 fn enum_type(&self, def_id: DefId, structural_type: TypeId) -> TypeId;
85 fn application(&self, base: TypeId, args: Vec<TypeId>) -> TypeId;
86
87 fn literal_string_atom(&self, atom: Atom) -> TypeId;
88 fn union_preserve_members(&self, members: Vec<TypeId>) -> TypeId;
89 fn readonly_type(&self, inner: TypeId) -> TypeId;
90 fn keyof(&self, inner: TypeId) -> TypeId;
91 fn index_access(&self, object_type: TypeId, index_type: TypeId) -> TypeId;
92 fn this_type(&self) -> TypeId;
93 fn no_infer(&self, inner: TypeId) -> TypeId;
94 fn unique_symbol(&self, symbol: SymbolRef) -> TypeId;
95 fn infer(&self, info: TypeParamInfo) -> TypeId;
96 fn string_intrinsic(&self, kind: StringIntrinsicKind, type_arg: TypeId) -> TypeId;
97
98 fn get_class_base_type(&self, symbol_id: SymbolId) -> Option<TypeId>;
102
103 fn is_identity_comparable_type(&self, type_id: TypeId) -> bool;
108}
109
110impl TypeDatabase for TypeInterner {
111 fn intern(&self, key: TypeData) -> TypeId {
112 Self::intern(self, key)
113 }
114
115 fn lookup(&self, id: TypeId) -> Option<TypeData> {
116 Self::lookup(self, id)
117 }
118
119 fn intern_string(&self, s: &str) -> Atom {
120 Self::intern_string(self, s)
121 }
122
123 fn resolve_atom(&self, atom: Atom) -> String {
124 Self::resolve_atom(self, atom)
125 }
126
127 fn resolve_atom_ref(&self, atom: Atom) -> Arc<str> {
128 Self::resolve_atom_ref(self, atom)
129 }
130
131 fn type_list(&self, id: TypeListId) -> Arc<[TypeId]> {
132 Self::type_list(self, id)
133 }
134
135 fn tuple_list(&self, id: TupleListId) -> Arc<[TupleElement]> {
136 Self::tuple_list(self, id)
137 }
138
139 fn template_list(&self, id: TemplateLiteralId) -> Arc<[TemplateSpan]> {
140 Self::template_list(self, id)
141 }
142
143 fn object_shape(&self, id: ObjectShapeId) -> Arc<ObjectShape> {
144 Self::object_shape(self, id)
145 }
146
147 fn object_property_index(&self, shape_id: ObjectShapeId, name: Atom) -> PropertyLookup {
148 Self::object_property_index(self, shape_id, name)
149 }
150
151 fn function_shape(&self, id: FunctionShapeId) -> Arc<FunctionShape> {
152 Self::function_shape(self, id)
153 }
154
155 fn callable_shape(&self, id: CallableShapeId) -> Arc<CallableShape> {
156 Self::callable_shape(self, id)
157 }
158
159 fn conditional_type(&self, id: ConditionalTypeId) -> Arc<ConditionalType> {
160 Self::conditional_type(self, id)
161 }
162
163 fn mapped_type(&self, id: MappedTypeId) -> Arc<MappedType> {
164 Self::mapped_type(self, id)
165 }
166
167 fn type_application(&self, id: TypeApplicationId) -> Arc<TypeApplication> {
168 Self::type_application(self, id)
169 }
170
171 fn literal_string(&self, value: &str) -> TypeId {
172 Self::literal_string(self, value)
173 }
174
175 fn literal_number(&self, value: f64) -> TypeId {
176 Self::literal_number(self, value)
177 }
178
179 fn literal_boolean(&self, value: bool) -> TypeId {
180 Self::literal_boolean(self, value)
181 }
182
183 fn literal_bigint(&self, value: &str) -> TypeId {
184 Self::literal_bigint(self, value)
185 }
186
187 fn literal_bigint_with_sign(&self, negative: bool, digits: &str) -> TypeId {
188 Self::literal_bigint_with_sign(self, negative, digits)
189 }
190
191 fn union(&self, members: Vec<TypeId>) -> TypeId {
192 Self::union(self, members)
193 }
194
195 fn union_from_sorted_vec(&self, flat: Vec<TypeId>) -> TypeId {
196 Self::union_from_sorted_vec(self, flat)
197 }
198
199 fn union2(&self, left: TypeId, right: TypeId) -> TypeId {
200 Self::union2(self, left, right)
201 }
202
203 fn union3(&self, first: TypeId, second: TypeId, third: TypeId) -> TypeId {
204 Self::union3(self, first, second, third)
205 }
206
207 fn intersection(&self, members: Vec<TypeId>) -> TypeId {
208 Self::intersection(self, members)
209 }
210
211 fn intersection2(&self, left: TypeId, right: TypeId) -> TypeId {
212 Self::intersection2(self, left, right)
213 }
214
215 fn intersect_types_raw2(&self, left: TypeId, right: TypeId) -> TypeId {
216 Self::intersect_types_raw2(self, left, right)
217 }
218
219 fn array(&self, element: TypeId) -> TypeId {
220 Self::array(self, element)
221 }
222
223 fn tuple(&self, elements: Vec<TupleElement>) -> TypeId {
224 Self::tuple(self, elements)
225 }
226
227 fn object(&self, properties: Vec<PropertyInfo>) -> TypeId {
228 Self::object(self, properties)
229 }
230
231 fn object_with_flags(&self, properties: Vec<PropertyInfo>, flags: ObjectFlags) -> TypeId {
232 Self::object_with_flags(self, properties, flags)
233 }
234
235 fn object_with_flags_and_symbol(
236 &self,
237 properties: Vec<PropertyInfo>,
238 flags: ObjectFlags,
239 symbol: Option<SymbolId>,
240 ) -> TypeId {
241 Self::object_with_flags_and_symbol(self, properties, flags, symbol)
242 }
243
244 fn object_with_index(&self, shape: ObjectShape) -> TypeId {
245 Self::object_with_index(self, shape)
246 }
247
248 fn function(&self, shape: FunctionShape) -> TypeId {
249 Self::function(self, shape)
250 }
251
252 fn callable(&self, shape: CallableShape) -> TypeId {
253 Self::callable(self, shape)
254 }
255
256 fn template_literal(&self, spans: Vec<TemplateSpan>) -> TypeId {
257 Self::template_literal(self, spans)
258 }
259
260 fn conditional(&self, conditional: ConditionalType) -> TypeId {
261 Self::conditional(self, conditional)
262 }
263
264 fn mapped(&self, mapped: MappedType) -> TypeId {
265 Self::mapped(self, mapped)
266 }
267
268 fn reference(&self, symbol: SymbolRef) -> TypeId {
269 Self::reference(self, symbol)
270 }
271
272 fn lazy(&self, def_id: DefId) -> TypeId {
273 Self::lazy(self, def_id)
274 }
275
276 fn bound_parameter(&self, index: u32) -> TypeId {
277 Self::bound_parameter(self, index)
278 }
279
280 fn recursive(&self, depth: u32) -> TypeId {
281 Self::recursive(self, depth)
282 }
283
284 fn type_param(&self, info: TypeParamInfo) -> TypeId {
285 Self::type_param(self, info)
286 }
287
288 fn type_query(&self, symbol: SymbolRef) -> TypeId {
289 Self::type_query(self, symbol)
290 }
291
292 fn enum_type(&self, def_id: DefId, structural_type: TypeId) -> TypeId {
293 Self::enum_type(self, def_id, structural_type)
294 }
295
296 fn application(&self, base: TypeId, args: Vec<TypeId>) -> TypeId {
297 Self::application(self, base, args)
298 }
299
300 fn literal_string_atom(&self, atom: Atom) -> TypeId {
301 Self::literal_string_atom(self, atom)
302 }
303
304 fn union_preserve_members(&self, members: Vec<TypeId>) -> TypeId {
305 Self::union_preserve_members(self, members)
306 }
307
308 fn readonly_type(&self, inner: TypeId) -> TypeId {
309 Self::readonly_type(self, inner)
310 }
311
312 fn keyof(&self, inner: TypeId) -> TypeId {
313 Self::keyof(self, inner)
314 }
315
316 fn index_access(&self, object_type: TypeId, index_type: TypeId) -> TypeId {
317 Self::index_access(self, object_type, index_type)
318 }
319
320 fn this_type(&self) -> TypeId {
321 Self::this_type(self)
322 }
323
324 fn no_infer(&self, inner: TypeId) -> TypeId {
325 Self::no_infer(self, inner)
326 }
327
328 fn unique_symbol(&self, symbol: SymbolRef) -> TypeId {
329 Self::unique_symbol(self, symbol)
330 }
331
332 fn infer(&self, info: TypeParamInfo) -> TypeId {
333 Self::infer(self, info)
334 }
335
336 fn string_intrinsic(&self, kind: StringIntrinsicKind, type_arg: TypeId) -> TypeId {
337 Self::string_intrinsic(self, kind, type_arg)
338 }
339
340 fn get_class_base_type(&self, _symbol_id: SymbolId) -> Option<TypeId> {
341 None
344 }
345
346 fn is_identity_comparable_type(&self, type_id: TypeId) -> bool {
347 Self::is_identity_comparable_type(self, type_id)
348 }
349}
350
351impl TypeResolver for TypeInterner {
359 fn resolve_ref(&self, _symbol: SymbolRef, _interner: &dyn TypeDatabase) -> Option<TypeId> {
360 None
361 }
362
363 fn get_boxed_type(&self, kind: IntrinsicKind) -> Option<TypeId> {
364 TypeInterner::get_boxed_type(self, kind)
365 }
366
367 fn get_array_base_type(&self) -> Option<TypeId> {
368 self.get_array_base_type()
369 }
370
371 fn get_array_base_type_params(&self) -> &[TypeParamInfo] {
372 self.get_array_base_type_params()
373 }
374}
375
376pub trait QueryDatabase: TypeDatabase + TypeResolver {
381 fn as_type_database(&self) -> &dyn TypeDatabase;
383
384 #[inline]
386 fn factory(&self) -> TypeFactory<'_> {
387 TypeFactory::new(self.as_type_database())
388 }
389
390 fn register_array_base_type(&self, _type_id: TypeId, _type_params: Vec<TypeParamInfo>) {}
397
398 fn register_boxed_type(&self, _kind: IntrinsicKind, _type_id: TypeId) {}
404
405 fn evaluate_conditional(&self, cond: &ConditionalType) -> TypeId {
406 crate::evaluation::evaluate::evaluate_conditional(self.as_type_database(), cond)
407 }
408
409 fn evaluate_index_access(&self, object_type: TypeId, index_type: TypeId) -> TypeId {
410 self.evaluate_index_access_with_options(
411 object_type,
412 index_type,
413 self.no_unchecked_indexed_access(),
414 )
415 }
416
417 fn evaluate_index_access_with_options(
418 &self,
419 object_type: TypeId,
420 index_type: TypeId,
421 no_unchecked_indexed_access: bool,
422 ) -> TypeId {
423 crate::evaluation::evaluate::evaluate_index_access_with_options(
424 self.as_type_database(),
425 object_type,
426 index_type,
427 no_unchecked_indexed_access,
428 )
429 }
430
431 fn evaluate_type(&self, type_id: TypeId) -> TypeId {
432 crate::evaluation::evaluate::evaluate_type(self.as_type_database(), type_id)
433 }
434
435 fn evaluate_type_with_options(
436 &self,
437 type_id: TypeId,
438 no_unchecked_indexed_access: bool,
439 ) -> TypeId {
440 if !no_unchecked_indexed_access {
441 return self.evaluate_type(type_id);
442 }
443
444 let mut evaluator =
445 crate::evaluation::evaluate::TypeEvaluator::new(self.as_type_database());
446 evaluator.set_no_unchecked_indexed_access(no_unchecked_indexed_access);
447 evaluator.evaluate(type_id)
448 }
449
450 fn evaluate_mapped(&self, mapped: &MappedType) -> TypeId {
451 crate::evaluation::evaluate::evaluate_mapped(self.as_type_database(), mapped)
452 }
453
454 fn lookup_application_eval_cache(
456 &self,
457 _def_id: DefId,
458 _args: &[TypeId],
459 _no_unchecked_indexed_access: bool,
460 ) -> Option<TypeId> {
461 None
462 }
463
464 fn insert_application_eval_cache(
466 &self,
467 _def_id: DefId,
468 _args: &[TypeId],
469 _no_unchecked_indexed_access: bool,
470 _result: TypeId,
471 ) {
472 }
473
474 fn evaluate_keyof(&self, operand: TypeId) -> TypeId {
475 crate::evaluation::evaluate::evaluate_keyof(self.as_type_database(), operand)
476 }
477
478 fn narrow(&self, type_id: TypeId, narrower: TypeId) -> TypeId
479 where
480 Self: Sized,
481 {
482 crate::narrowing::NarrowingContext::new(self).narrow(type_id, narrower)
483 }
484
485 fn resolve_property_access(
486 &self,
487 object_type: TypeId,
488 prop_name: &str,
489 ) -> crate::operations::property::PropertyAccessResult;
490
491 fn resolve_property_access_with_options(
492 &self,
493 object_type: TypeId,
494 prop_name: &str,
495 no_unchecked_indexed_access: bool,
496 ) -> crate::operations::property::PropertyAccessResult;
497
498 fn property_access_type(
499 &self,
500 object_type: TypeId,
501 prop_name: &str,
502 ) -> crate::operations::property::PropertyAccessResult {
503 self.resolve_property_access_with_options(
504 object_type,
505 prop_name,
506 self.no_unchecked_indexed_access(),
507 )
508 }
509
510 fn no_unchecked_indexed_access(&self) -> bool {
511 false
512 }
513
514 fn set_no_unchecked_indexed_access(&self, _enabled: bool) {}
515
516 fn contextual_property_type(&self, expected: TypeId, prop_name: &str) -> Option<TypeId> {
517 let ctx = crate::ContextualTypeContext::with_expected(self.as_type_database(), expected);
518 ctx.get_property_type(prop_name)
519 }
520
521 fn is_property_readonly(&self, object_type: TypeId, prop_name: &str) -> bool {
522 crate::operations::property::property_is_readonly(
523 self.as_type_database(),
524 object_type,
525 prop_name,
526 )
527 }
528
529 fn is_readonly_index_signature(
530 &self,
531 object_type: TypeId,
532 wants_string: bool,
533 wants_number: bool,
534 ) -> bool {
535 crate::operations::property::is_readonly_index_signature(
536 self.as_type_database(),
537 object_type,
538 wants_string,
539 wants_number,
540 )
541 }
542
543 fn resolve_element_access(
545 &self,
546 object_type: TypeId,
547 index_type: TypeId,
548 literal_index: Option<usize>,
549 ) -> ElementAccessResult {
550 let evaluator = ElementAccessEvaluator::new(self.as_type_database());
551 evaluator.resolve_element_access(object_type, index_type, literal_index)
552 }
553
554 fn resolve_element_access_type(
556 &self,
557 object_type: TypeId,
558 index_type: TypeId,
559 literal_index: Option<usize>,
560 ) -> TypeId {
561 match self.resolve_element_access(object_type, index_type, literal_index) {
562 crate::element_access::ElementAccessResult::Success(type_id) => type_id,
563 _ => TypeId::ERROR,
564 }
565 }
566
567 fn collect_object_spread_properties(&self, spread_type: TypeId) -> Vec<PropertyInfo> {
569 let builder = ObjectLiteralBuilder::new(self.as_type_database());
570 builder.collect_spread_properties(spread_type)
571 }
572
573 fn get_index_signatures(&self, type_id: TypeId) -> IndexInfo;
575
576 fn is_nullish_type(&self, type_id: TypeId) -> bool;
578
579 fn remove_nullish(&self, type_id: TypeId) -> TypeId;
581
582 fn canonical_id(&self, type_id: TypeId) -> TypeId;
595
596 fn is_subtype_of(&self, source: TypeId, target: TypeId) -> bool {
608 self.is_subtype_of_with_flags(source, target, 0)
611 }
612
613 fn is_subtype_of_with_flags(&self, source: TypeId, target: TypeId, flags: u16) -> bool {
617 crate::relations::subtype::is_subtype_of_with_flags(
620 self.as_type_database(),
621 source,
622 target,
623 flags,
624 )
625 }
626
627 fn is_assignable_to(&self, source: TypeId, target: TypeId) -> bool {
642 self.is_assignable_to_with_flags(source, target, 0)
645 }
646
647 fn is_assignable_to_with_flags(&self, source: TypeId, target: TypeId, flags: u16) -> bool;
651
652 fn lookup_subtype_cache(&self, _key: RelationCacheKey) -> Option<bool> {
656 None
657 }
658
659 fn insert_subtype_cache(&self, _key: RelationCacheKey, _result: bool) {}
662
663 fn lookup_assignability_cache(&self, _key: RelationCacheKey) -> Option<bool> {
667 None
668 }
669
670 fn insert_assignability_cache(&self, _key: RelationCacheKey, _result: bool) {}
673
674 fn new_inference_context(&self) -> crate::inference::infer::InferenceContext<'_> {
675 crate::inference::infer::InferenceContext::new(self.as_type_database())
676 }
677
678 fn get_type_param_variance(&self, def_id: DefId) -> Option<Arc<[Variance]>>;
683}
684
685impl QueryDatabase for TypeInterner {
686 fn as_type_database(&self) -> &dyn TypeDatabase {
687 self
688 }
689
690 fn register_array_base_type(&self, type_id: TypeId, type_params: Vec<TypeParamInfo>) {
691 self.set_array_base_type(type_id, type_params);
692 }
693
694 fn register_boxed_type(&self, kind: IntrinsicKind, type_id: TypeId) {
695 TypeInterner::set_boxed_type(self, kind, type_id);
696 }
697
698 fn get_index_signatures(&self, type_id: TypeId) -> IndexInfo {
699 match self.lookup(type_id) {
700 Some(TypeData::ObjectWithIndex(shape_id)) => {
701 let shape = self.object_shape(shape_id);
702 IndexInfo {
703 string_index: shape.string_index.clone(),
704 number_index: shape.number_index.clone(),
705 }
706 }
707 Some(TypeData::Array(element)) => {
708 IndexInfo {
710 string_index: None,
711 number_index: Some(crate::types::IndexSignature {
712 key_type: TypeId::NUMBER,
713 value_type: element,
714 readonly: false,
715 }),
716 }
717 }
718 Some(TypeData::Tuple(elements_id)) => {
719 let elements = self.tuple_list(elements_id);
721 let element_types: Vec<TypeId> = elements.iter().map(|e| e.type_id).collect();
722 let value_type = if element_types.is_empty() {
723 TypeId::UNDEFINED
724 } else if element_types.len() == 1 {
725 element_types[0]
726 } else {
727 self.union(element_types)
728 };
729 IndexInfo {
730 string_index: None,
731 number_index: Some(crate::types::IndexSignature {
732 key_type: TypeId::NUMBER,
733 value_type,
734 readonly: false,
735 }),
736 }
737 }
738 Some(TypeData::Union(members_id)) => {
739 let members = self.type_list(members_id);
741 let mut string_indices = Vec::new();
742 let mut number_indices = Vec::new();
743
744 for &member in members.iter() {
745 let info = self.get_index_signatures(member);
746 if let Some(sig) = info.string_index {
747 string_indices.push(sig);
748 }
749 if let Some(sig) = info.number_index {
750 number_indices.push(sig);
751 }
752 }
753
754 let string_index = if string_indices.is_empty() {
756 None
757 } else {
758 Some(crate::types::IndexSignature {
759 key_type: TypeId::STRING,
760 value_type: self
761 .union(string_indices.iter().map(|s| s.value_type).collect()),
762 readonly: string_indices.iter().all(|s| s.readonly),
763 })
764 };
765
766 let number_index = if number_indices.is_empty() {
767 None
768 } else {
769 Some(crate::types::IndexSignature {
770 key_type: TypeId::NUMBER,
771 value_type: self
772 .union(number_indices.iter().map(|s| s.value_type).collect()),
773 readonly: number_indices.iter().all(|s| s.readonly),
774 })
775 };
776
777 IndexInfo {
778 string_index,
779 number_index,
780 }
781 }
782 Some(TypeData::Intersection(members_id)) => {
783 let members = self.type_list(members_id);
785 let mut string_index = None;
786 let mut number_index = None;
787
788 for &member in members.iter() {
789 let info = self.get_index_signatures(member);
790 if let Some(sig) = info.string_index {
791 string_index = Some(sig);
792 }
793 if let Some(sig) = info.number_index {
794 number_index = Some(sig);
795 }
796 }
797
798 IndexInfo {
799 string_index,
800 number_index,
801 }
802 }
803 _ => IndexInfo::default(),
804 }
805 }
806
807 fn is_nullish_type(&self, type_id: TypeId) -> bool {
808 narrowing::is_nullish_type(self, type_id)
809 }
810
811 fn remove_nullish(&self, type_id: TypeId) -> TypeId {
812 narrowing::remove_nullish(self, type_id)
813 }
814
815 fn is_assignable_to(&self, source: TypeId, target: TypeId) -> bool {
816 self.is_assignable_to_with_flags(source, target, 0)
818 }
819
820 fn is_assignable_to_with_flags(&self, source: TypeId, target: TypeId, flags: u16) -> bool {
821 use crate::relations::compat::CompatChecker;
822 let mut checker = CompatChecker::new(self);
823 if flags != 0 {
824 checker.apply_flags(flags);
825 }
826 checker.is_assignable(source, target)
827 }
828
829 fn resolve_property_access(
830 &self,
831 object_type: TypeId,
832 prop_name: &str,
833 ) -> crate::operations::property::PropertyAccessResult {
834 let evaluator = crate::operations::property::PropertyAccessEvaluator::new(self);
837 evaluator.resolve_property_access(object_type, prop_name)
838 }
839
840 fn resolve_property_access_with_options(
841 &self,
842 object_type: TypeId,
843 prop_name: &str,
844 no_unchecked_indexed_access: bool,
845 ) -> crate::operations::property::PropertyAccessResult {
846 let mut evaluator = crate::operations::property::PropertyAccessEvaluator::new(self);
847 evaluator.set_no_unchecked_indexed_access(no_unchecked_indexed_access);
848 evaluator.resolve_property_access(object_type, prop_name)
849 }
850
851 fn get_type_param_variance(&self, _def_id: DefId) -> Option<Arc<[Variance]>> {
852 None
855 }
856
857 fn canonical_id(&self, type_id: TypeId) -> TypeId {
858 use crate::canonicalize::Canonicalizer;
860 let mut canon = Canonicalizer::new(self, self);
861 canon.canonicalize(type_id)
862 }
863}