1#![warn(missing_docs)]
2#![doc = "TypeScript 高级类型系统实现"]
3
4use std::{
5 collections::HashMap,
6 hash::{Hash, Hasher},
7 rc::Rc,
8};
9
10#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub enum ConditionalModifier {
13 None,
15 Infer {
17 type_param: String,
19 },
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24pub struct Conditional {
25 pub check_type: Box<TsValue>,
27 pub extends_type: Box<TsValue>,
29 pub true_type: Box<TsValue>,
31 pub false_type: Box<TsValue>,
33 pub modifier: ConditionalModifier,
35}
36
37impl Conditional {
38 pub fn new(check_type: TsValue, extends_type: TsValue, true_type: TsValue, false_type: TsValue) -> Self {
40 Self {
41 check_type: Box::new(check_type),
42 extends_type: Box::new(extends_type),
43 true_type: Box::new(true_type),
44 false_type: Box::new(false_type),
45 modifier: ConditionalModifier::None,
46 }
47 }
48
49 pub fn with_infer(check_type: TsValue, extends_type: TsValue, type_param: String) -> Self {
51 Self {
52 check_type: Box::new(check_type),
53 extends_type: Box::new(extends_type),
54 true_type: Box::new(TsValue::Undefined),
55 false_type: Box::new(TsValue::Undefined),
56 modifier: ConditionalModifier::Infer { type_param },
57 }
58 }
59
60 pub fn with_true_type(mut self, true_type: TsValue) -> Self {
62 self.true_type = Box::new(true_type);
63 self
64 }
65
66 pub fn with_false_type(mut self, false_type: TsValue) -> Self {
68 self.false_type = Box::new(false_type);
69 self
70 }
71}
72
73#[derive(Debug, Clone, PartialEq, Eq, Hash)]
75pub enum MappedConstraint {
76 None,
78 Optional,
80 Required,
82 Readonly,
84 Writable,
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Hash)]
90pub struct MappedKeyModifier {
91 pub optional: bool,
93 pub readonly: bool,
95}
96
97impl Default for MappedKeyModifier {
98 fn default() -> Self {
99 Self { optional: false, readonly: false }
100 }
101}
102
103#[derive(Debug, Clone, PartialEq, Eq, Hash)]
105pub struct Mapped {
106 pub type_param: String,
108 pub constraint: Box<TsValue>,
110 pub value_type: Box<TsValue>,
112 pub key_modifier: MappedKeyModifier,
114 pub constraint_type: MappedConstraint,
116}
117
118impl Mapped {
119 pub fn new(type_param: String, constraint: TsValue, value_type: TsValue) -> Self {
121 Self {
122 type_param,
123 constraint: Box::new(constraint),
124 value_type: Box::new(value_type),
125 key_modifier: MappedKeyModifier::default(),
126 constraint_type: MappedConstraint::None,
127 }
128 }
129
130 pub fn with_optional(mut self) -> Self {
132 self.key_modifier.optional = true;
133 self
134 }
135
136 pub fn with_readonly(mut self) -> Self {
138 self.key_modifier.readonly = true;
139 self
140 }
141
142 pub fn with_constraint(mut self, constraint: MappedConstraint) -> Self {
144 self.constraint_type = constraint;
145 self
146 }
147}
148
149#[derive(Debug, Clone, PartialEq, Eq, Hash)]
151pub enum TemplateLiteralPart {
152 String(String),
154 Type(Box<TsValue>),
156 Number,
158 StringType,
160 BigInt,
162 Union(Vec<TsValue>),
164}
165
166#[derive(Debug, Clone, PartialEq, Eq, Hash)]
168pub struct TemplateLiteral {
169 pub parts: Vec<TemplateLiteralPart>,
171}
172
173impl TemplateLiteral {
174 pub fn new() -> Self {
176 Self { parts: Vec::new() }
177 }
178
179 pub fn from_parts(parts: Vec<TemplateLiteralPart>) -> Self {
181 Self { parts }
182 }
183
184 pub fn push_string(&mut self, s: String) {
186 self.parts.push(TemplateLiteralPart::String(s));
187 }
188
189 pub fn push_type(&mut self, ty: TsValue) {
191 self.parts.push(TemplateLiteralPart::Type(Box::new(ty)));
192 }
193
194 pub fn push_number(&mut self) {
196 self.parts.push(TemplateLiteralPart::Number);
197 }
198
199 pub fn push_string_type(&mut self) {
201 self.parts.push(TemplateLiteralPart::StringType);
202 }
203
204 pub fn push_bigint(&mut self) {
206 self.parts.push(TemplateLiteralPart::BigInt);
207 }
208}
209
210impl Default for TemplateLiteral {
211 fn default() -> Self {
212 Self::new()
213 }
214}
215
216#[derive(Debug, Clone, PartialEq)]
218pub struct InferenceResult {
219 pub inferred_types: HashMap<String, TsValue>,
221 pub success: bool,
223}
224
225impl InferenceResult {
226 pub fn success(inferred_types: HashMap<String, TsValue>) -> Self {
228 Self { inferred_types, success: true }
229 }
230
231 pub fn failure() -> Self {
233 Self { inferred_types: HashMap::new(), success: false }
234 }
235
236 pub fn merge(self, other: InferenceResult) -> Self {
238 if !self.success || !other.success {
239 return InferenceResult::failure();
240 }
241 let mut merged = self.inferred_types;
242 merged.extend(other.inferred_types);
243 InferenceResult::success(merged)
244 }
245}
246
247pub enum TsValue {
249 Undefined,
251 Null,
253 Boolean(bool),
255 Number(f64),
257 String(String),
259 Object(HashMap<String, TsValue>),
261 Array(Vec<TsValue>),
263 Function(Rc<dyn Fn(&[TsValue]) -> TsValue>),
265 Error(String),
267 Union(Vec<TsValue>),
269 Generic(String, Vec<TsValue>),
271 Symbol(String),
273 BigInt(i128),
275 Date(i64),
277 RegExp(String),
279 Map(Vec<(TsValue, TsValue)>),
281 Set(Vec<TsValue>),
283 Promise(Box<TsValue>),
285 Iterable(Box<dyn Iterator<Item = TsValue>>),
287 Conditional(Conditional),
289 Mapped(Mapped),
291 TemplateLiteral(TemplateLiteral),
293 KeyOf(Box<TsValue>),
295 TypeOf(Box<TsValue>),
297 IndexedAccess {
299 object_type: Box<TsValue>,
301 index_type: Box<TsValue>,
303 },
304 Tuple(Vec<TsValue>),
306 Readonly(Box<TsValue>),
308 Nullable(Box<TsValue>),
310 NonNullable(Box<TsValue>),
312 Infer {
314 type_param: String,
316 constraint: Option<Box<TsValue>>,
318 },
319 FunctionType {
321 params: Vec<(String, TsValue)>,
323 return_type: Box<TsValue>,
325 },
326 ConstructorType {
328 params: Vec<(String, TsValue)>,
330 return_type: Box<TsValue>,
332 },
333 ThisType,
335 Never,
337 Unknown,
339 Any,
341 Void,
343}
344
345impl PartialEq for TsValue {
346 fn eq(&self, other: &Self) -> bool {
347 match (self, other) {
348 (TsValue::Undefined, TsValue::Undefined) => true,
349 (TsValue::Null, TsValue::Null) => true,
350 (TsValue::Boolean(a), TsValue::Boolean(b)) => a == b,
351 (TsValue::Number(a), TsValue::Number(b)) => a.to_bits() == b.to_bits(),
352 (TsValue::String(a), TsValue::String(b)) => a == b,
353 (TsValue::Object(a), TsValue::Object(b)) => a == b,
354 (TsValue::Array(a), TsValue::Array(b)) => a == b,
355 (TsValue::Function(_), TsValue::Function(_)) => false,
356 (TsValue::Error(a), TsValue::Error(b)) => a == b,
357 (TsValue::Union(a), TsValue::Union(b)) => a == b,
358 (TsValue::Generic(name_a, args_a), TsValue::Generic(name_b, args_b)) => name_a == name_b && args_a == args_b,
359 (TsValue::Symbol(a), TsValue::Symbol(b)) => a == b,
360 (TsValue::BigInt(a), TsValue::BigInt(b)) => a == b,
361 (TsValue::Date(a), TsValue::Date(b)) => a == b,
362 (TsValue::RegExp(a), TsValue::RegExp(b)) => a == b,
363 (TsValue::Map(a), TsValue::Map(b)) => a == b,
364 (TsValue::Set(a), TsValue::Set(b)) => a == b,
365 (TsValue::Promise(a), TsValue::Promise(b)) => a == b,
366 (TsValue::Iterable(_), TsValue::Iterable(_)) => false,
367 (TsValue::Conditional(a), TsValue::Conditional(b)) => a == b,
368 (TsValue::Mapped(a), TsValue::Mapped(b)) => a == b,
369 (TsValue::TemplateLiteral(a), TsValue::TemplateLiteral(b)) => a == b,
370 (TsValue::KeyOf(a), TsValue::KeyOf(b)) => a == b,
371 (TsValue::TypeOf(a), TsValue::TypeOf(b)) => a == b,
372 (
373 TsValue::IndexedAccess { object_type: obj_a, index_type: idx_a },
374 TsValue::IndexedAccess { object_type: obj_b, index_type: idx_b },
375 ) => obj_a == obj_b && idx_a == idx_b,
376 (TsValue::Tuple(a), TsValue::Tuple(b)) => a == b,
377 (TsValue::Readonly(a), TsValue::Readonly(b)) => a == b,
378 (TsValue::Nullable(a), TsValue::Nullable(b)) => a == b,
379 (TsValue::NonNullable(a), TsValue::NonNullable(b)) => a == b,
380 (
381 TsValue::Infer { type_param: param_a, constraint: constraint_a },
382 TsValue::Infer { type_param: param_b, constraint: constraint_b },
383 ) => param_a == param_b && constraint_a == constraint_b,
384 (
385 TsValue::FunctionType { params: params_a, return_type: ret_a },
386 TsValue::FunctionType { params: params_b, return_type: ret_b },
387 ) => params_a == params_b && ret_a == ret_b,
388 (
389 TsValue::ConstructorType { params: params_a, return_type: ret_a },
390 TsValue::ConstructorType { params: params_b, return_type: ret_b },
391 ) => params_a == params_b && ret_a == ret_b,
392 (TsValue::ThisType, TsValue::ThisType) => true,
393 (TsValue::Never, TsValue::Never) => true,
394 (TsValue::Unknown, TsValue::Unknown) => true,
395 (TsValue::Any, TsValue::Any) => true,
396 (TsValue::Void, TsValue::Void) => true,
397 _ => false,
398 }
399 }
400}
401
402impl Eq for TsValue {}
403
404impl Clone for TsValue {
405 fn clone(&self) -> Self {
406 match self {
407 TsValue::Undefined => TsValue::Undefined,
408 TsValue::Null => TsValue::Null,
409 TsValue::Boolean(b) => TsValue::Boolean(*b),
410 TsValue::Number(n) => TsValue::Number(*n),
411 TsValue::String(s) => TsValue::String(s.clone()),
412 TsValue::Object(props) => TsValue::Object(props.clone()),
413 TsValue::Array(arr) => TsValue::Array(arr.clone()),
414 TsValue::Function(f) => TsValue::Function(Rc::clone(f)),
415 TsValue::Error(s) => TsValue::Error(s.clone()),
416 TsValue::Union(values) => TsValue::Union(values.clone()),
417 TsValue::Generic(name, args) => TsValue::Generic(name.clone(), args.clone()),
418 TsValue::Symbol(s) => TsValue::Symbol(s.clone()),
419 TsValue::BigInt(bi) => TsValue::BigInt(*bi),
420 TsValue::Date(d) => TsValue::Date(*d),
421 TsValue::RegExp(pattern) => TsValue::RegExp(pattern.clone()),
422 TsValue::Map(entries) => TsValue::Map(entries.clone()),
423 TsValue::Set(values) => TsValue::Set(values.clone()),
424 TsValue::Promise(value) => TsValue::Promise(value.clone()),
425 TsValue::Iterable(_) => TsValue::Undefined,
426 TsValue::Conditional(cond) => TsValue::Conditional(cond.clone()),
427 TsValue::Mapped(mapped) => TsValue::Mapped(mapped.clone()),
428 TsValue::TemplateLiteral(tpl) => TsValue::TemplateLiteral(tpl.clone()),
429 TsValue::KeyOf(ty) => TsValue::KeyOf(ty.clone()),
430 TsValue::TypeOf(ty) => TsValue::TypeOf(ty.clone()),
431 TsValue::IndexedAccess { object_type, index_type } => {
432 TsValue::IndexedAccess { object_type: object_type.clone(), index_type: index_type.clone() }
433 }
434 TsValue::Tuple(elements) => TsValue::Tuple(elements.clone()),
435 TsValue::Readonly(ty) => TsValue::Readonly(ty.clone()),
436 TsValue::Nullable(ty) => TsValue::Nullable(ty.clone()),
437 TsValue::NonNullable(ty) => TsValue::NonNullable(ty.clone()),
438 TsValue::Infer { type_param, constraint } => {
439 TsValue::Infer { type_param: type_param.clone(), constraint: constraint.clone() }
440 }
441 TsValue::FunctionType { params, return_type } => {
442 TsValue::FunctionType { params: params.clone(), return_type: return_type.clone() }
443 }
444 TsValue::ConstructorType { params, return_type } => {
445 TsValue::ConstructorType { params: params.clone(), return_type: return_type.clone() }
446 }
447 TsValue::ThisType => TsValue::ThisType,
448 TsValue::Never => TsValue::Never,
449 TsValue::Unknown => TsValue::Unknown,
450 TsValue::Any => TsValue::Any,
451 TsValue::Void => TsValue::Void,
452 }
453 }
454}
455
456impl std::fmt::Debug for TsValue {
457 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
458 match self {
459 TsValue::Undefined => write!(f, "Undefined"),
460 TsValue::Null => write!(f, "Null"),
461 TsValue::Boolean(_) => write!(f, "Boolean"),
462 TsValue::Number(_) => write!(f, "Number"),
463 TsValue::String(_) => write!(f, "String"),
464 TsValue::Object(_) => write!(f, "Object"),
465 TsValue::Array(_) => write!(f, "Array"),
466 TsValue::Function(_) => write!(f, "Function"),
467 TsValue::Error(_) => write!(f, "Error"),
468 TsValue::Union(_) => write!(f, "Union"),
469 TsValue::Generic(name, _) => write!(f, "Generic({})", name),
470 TsValue::Symbol(_) => write!(f, "Symbol"),
471 TsValue::BigInt(_) => write!(f, "BigInt"),
472 TsValue::Date(_) => write!(f, "Date"),
473 TsValue::RegExp(_) => write!(f, "RegExp"),
474 TsValue::Map(_) => write!(f, "Map"),
475 TsValue::Set(_) => write!(f, "Set"),
476 TsValue::Promise(_) => write!(f, "Promise"),
477 TsValue::Iterable(_) => write!(f, "Iterable"),
478 TsValue::Conditional(_) => write!(f, "Conditional"),
479 TsValue::Mapped(_) => write!(f, "Mapped"),
480 TsValue::TemplateLiteral(_) => write!(f, "TemplateLiteral"),
481 TsValue::KeyOf(_) => write!(f, "KeyOf"),
482 TsValue::TypeOf(_) => write!(f, "TypeOf"),
483 TsValue::IndexedAccess { .. } => write!(f, "IndexedAccess"),
484 TsValue::Tuple(_) => write!(f, "Tuple"),
485 TsValue::Readonly(_) => write!(f, "Readonly"),
486 TsValue::Nullable(_) => write!(f, "Nullable"),
487 TsValue::NonNullable(_) => write!(f, "NonNullable"),
488 TsValue::Infer { type_param, .. } => write!(f, "Infer({})", type_param),
489 TsValue::FunctionType { .. } => write!(f, "FunctionType"),
490 TsValue::ConstructorType { .. } => write!(f, "ConstructorType"),
491 TsValue::ThisType => write!(f, "ThisType"),
492 TsValue::Never => write!(f, "Never"),
493 TsValue::Unknown => write!(f, "Unknown"),
494 TsValue::Any => write!(f, "Any"),
495 TsValue::Void => write!(f, "Void"),
496 }
497 }
498}
499
500impl Hash for TsValue {
501 fn hash<H: Hasher>(&self, state: &mut H) {
502 match self {
503 TsValue::Undefined => 0.hash(state),
504 TsValue::Null => 1.hash(state),
505 TsValue::Boolean(b) => {
506 2.hash(state);
507 b.hash(state);
508 }
509 TsValue::Number(n) => {
510 3.hash(state);
511 n.to_bits().hash(state);
512 }
513 TsValue::String(s) => {
514 4.hash(state);
515 s.hash(state);
516 }
517 TsValue::Object(props) => {
518 5.hash(state);
519 props.len().hash(state);
520 for (key, value) in props {
521 key.hash(state);
522 value.hash(state);
523 }
524 }
525 TsValue::Array(arr) => {
526 6.hash(state);
527 arr.len().hash(state);
528 for item in arr {
529 item.hash(state);
530 }
531 }
532 TsValue::Function(_) => 7.hash(state),
533 TsValue::Error(s) => {
534 8.hash(state);
535 s.hash(state);
536 }
537 TsValue::Union(values) => {
538 9.hash(state);
539 values.len().hash(state);
540 for value in values {
541 value.hash(state);
542 }
543 }
544 TsValue::Generic(name, args) => {
545 10.hash(state);
546 name.hash(state);
547 args.len().hash(state);
548 for arg in args {
549 arg.hash(state);
550 }
551 }
552 TsValue::Symbol(s) => {
553 11.hash(state);
554 s.hash(state);
555 }
556 TsValue::BigInt(bi) => {
557 12.hash(state);
558 bi.hash(state);
559 }
560 TsValue::Date(d) => {
561 13.hash(state);
562 d.hash(state);
563 }
564 TsValue::RegExp(pattern) => {
565 14.hash(state);
566 pattern.hash(state);
567 }
568 TsValue::Map(entries) => {
569 15.hash(state);
570 entries.len().hash(state);
571 for (key, value) in entries {
572 key.hash(state);
573 value.hash(state);
574 }
575 }
576 TsValue::Set(values) => {
577 16.hash(state);
578 values.len().hash(state);
579 for value in values {
580 value.hash(state);
581 }
582 }
583 TsValue::Promise(value) => {
584 17.hash(state);
585 value.hash(state);
586 }
587 TsValue::Iterable(_) => 18.hash(state),
588 TsValue::Conditional(cond) => {
589 19.hash(state);
590 cond.hash(state);
591 }
592 TsValue::Mapped(mapped) => {
593 20.hash(state);
594 mapped.hash(state);
595 }
596 TsValue::TemplateLiteral(tpl) => {
597 21.hash(state);
598 tpl.hash(state);
599 }
600 TsValue::KeyOf(ty) => {
601 22.hash(state);
602 ty.hash(state);
603 }
604 TsValue::TypeOf(ty) => {
605 23.hash(state);
606 ty.hash(state);
607 }
608 TsValue::IndexedAccess { object_type, index_type } => {
609 24.hash(state);
610 object_type.hash(state);
611 index_type.hash(state);
612 }
613 TsValue::Tuple(elements) => {
614 25.hash(state);
615 elements.len().hash(state);
616 for elem in elements {
617 elem.hash(state);
618 }
619 }
620 TsValue::Readonly(ty) => {
621 26.hash(state);
622 ty.hash(state);
623 }
624 TsValue::Nullable(ty) => {
625 27.hash(state);
626 ty.hash(state);
627 }
628 TsValue::NonNullable(ty) => {
629 28.hash(state);
630 ty.hash(state);
631 }
632 TsValue::Infer { type_param, constraint } => {
633 29.hash(state);
634 type_param.hash(state);
635 constraint.hash(state);
636 }
637 TsValue::FunctionType { params, return_type } => {
638 30.hash(state);
639 params.len().hash(state);
640 for (name, ty) in params {
641 name.hash(state);
642 ty.hash(state);
643 }
644 return_type.hash(state);
645 }
646 TsValue::ConstructorType { params, return_type } => {
647 31.hash(state);
648 params.len().hash(state);
649 for (name, ty) in params {
650 name.hash(state);
651 ty.hash(state);
652 }
653 return_type.hash(state);
654 }
655 TsValue::ThisType => 32.hash(state),
656 TsValue::Never => 33.hash(state),
657 TsValue::Unknown => 34.hash(state),
658 TsValue::Any => 35.hash(state),
659 TsValue::Void => 36.hash(state),
660 }
661 }
662}
663
664impl TsValue {
665 pub fn is_undefined(&self) -> bool {
667 matches!(self, TsValue::Undefined)
668 }
669
670 pub fn is_null(&self) -> bool {
672 matches!(self, TsValue::Null)
673 }
674
675 pub fn is_boolean(&self) -> bool {
677 matches!(self, TsValue::Boolean(_))
678 }
679
680 pub fn is_number(&self) -> bool {
682 matches!(self, TsValue::Number(_))
683 }
684
685 pub fn is_string(&self) -> bool {
687 matches!(self, TsValue::String(_))
688 }
689
690 pub fn is_object(&self) -> bool {
692 matches!(self, TsValue::Object(_))
693 }
694
695 pub fn is_array(&self) -> bool {
697 matches!(self, TsValue::Array(_))
698 }
699
700 pub fn is_function(&self) -> bool {
702 matches!(self, TsValue::Function(_))
703 }
704
705 pub fn is_error(&self) -> bool {
707 matches!(self, TsValue::Error(_))
708 }
709
710 pub fn is_union(&self) -> bool {
712 matches!(self, TsValue::Union(_))
713 }
714
715 pub fn is_generic(&self) -> bool {
717 matches!(self, TsValue::Generic(_, _))
718 }
719
720 pub fn is_symbol(&self) -> bool {
722 matches!(self, TsValue::Symbol(_))
723 }
724
725 pub fn is_bigint(&self) -> bool {
727 matches!(self, TsValue::BigInt(_))
728 }
729
730 pub fn is_date(&self) -> bool {
732 matches!(self, TsValue::Date(_))
733 }
734
735 pub fn is_regexp(&self) -> bool {
737 matches!(self, TsValue::RegExp(_))
738 }
739
740 pub fn is_map(&self) -> bool {
742 matches!(self, TsValue::Map(_))
743 }
744
745 pub fn is_set(&self) -> bool {
747 matches!(self, TsValue::Set(_))
748 }
749
750 pub fn is_promise(&self) -> bool {
752 matches!(self, TsValue::Promise(_))
753 }
754
755 pub fn is_iterable(&self) -> bool {
757 matches!(self, TsValue::Iterable(_))
758 }
759
760 pub fn is_conditional(&self) -> bool {
762 matches!(self, TsValue::Conditional(_))
763 }
764
765 pub fn is_mapped(&self) -> bool {
767 matches!(self, TsValue::Mapped(_))
768 }
769
770 pub fn is_template_literal(&self) -> bool {
772 matches!(self, TsValue::TemplateLiteral(_))
773 }
774
775 pub fn is_keyof(&self) -> bool {
777 matches!(self, TsValue::KeyOf(_))
778 }
779
780 pub fn is_typeof(&self) -> bool {
782 matches!(self, TsValue::TypeOf(_))
783 }
784
785 pub fn is_indexed_access(&self) -> bool {
787 matches!(self, TsValue::IndexedAccess { .. })
788 }
789
790 pub fn is_tuple(&self) -> bool {
792 matches!(self, TsValue::Tuple(_))
793 }
794
795 pub fn is_readonly(&self) -> bool {
797 matches!(self, TsValue::Readonly(_))
798 }
799
800 pub fn is_nullable(&self) -> bool {
802 matches!(self, TsValue::Nullable(_))
803 }
804
805 pub fn is_non_nullable(&self) -> bool {
807 matches!(self, TsValue::NonNullable(_))
808 }
809
810 pub fn is_infer(&self) -> bool {
812 matches!(self, TsValue::Infer { .. })
813 }
814
815 pub fn is_function_type(&self) -> bool {
817 matches!(self, TsValue::FunctionType { .. })
818 }
819
820 pub fn is_constructor_type(&self) -> bool {
822 matches!(self, TsValue::ConstructorType { .. })
823 }
824
825 pub fn is_this_type(&self) -> bool {
827 matches!(self, TsValue::ThisType)
828 }
829
830 pub fn is_never(&self) -> bool {
832 matches!(self, TsValue::Never)
833 }
834
835 pub fn is_unknown(&self) -> bool {
837 matches!(self, TsValue::Unknown)
838 }
839
840 pub fn is_any(&self) -> bool {
842 matches!(self, TsValue::Any)
843 }
844
845 pub fn is_void(&self) -> bool {
847 matches!(self, TsValue::Void)
848 }
849
850 pub fn to_boolean(&self) -> bool {
852 match self {
853 TsValue::Undefined => false,
854 TsValue::Null => false,
855 TsValue::Boolean(b) => *b,
856 TsValue::Number(n) => *n != 0.0 && !n.is_nan(),
857 TsValue::String(s) => !s.is_empty(),
858 TsValue::Object(_) => true,
859 TsValue::Array(_) => true,
860 TsValue::Function(_) => true,
861 TsValue::Error(_) => true,
862 TsValue::Union(values) => !values.is_empty(),
863 TsValue::Generic(_, _) => true,
864 TsValue::Symbol(_) => true,
865 TsValue::BigInt(bi) => *bi != 0,
866 TsValue::Date(_) => true,
867 TsValue::RegExp(_) => true,
868 TsValue::Map(entries) => !entries.is_empty(),
869 TsValue::Set(values) => !values.is_empty(),
870 TsValue::Promise(_) => true,
871 TsValue::Iterable(_) => true,
872 TsValue::Conditional(_) => true,
873 TsValue::Mapped(_) => true,
874 TsValue::TemplateLiteral(_) => true,
875 TsValue::KeyOf(_) => true,
876 TsValue::TypeOf(_) => true,
877 TsValue::IndexedAccess { .. } => true,
878 TsValue::Tuple(_) => true,
879 TsValue::Readonly(_) => true,
880 TsValue::Nullable(_) => true,
881 TsValue::NonNullable(_) => true,
882 TsValue::Infer { .. } => true,
883 TsValue::FunctionType { .. } => true,
884 TsValue::ConstructorType { .. } => true,
885 TsValue::ThisType => true,
886 TsValue::Never => false,
887 TsValue::Unknown => true,
888 TsValue::Any => true,
889 TsValue::Void => false,
890 }
891 }
892
893 pub fn to_number(&self) -> f64 {
895 match self {
896 TsValue::Undefined => f64::NAN,
897 TsValue::Null => 0.0,
898 TsValue::Boolean(b) => {
899 if *b {
900 1.0
901 }
902 else {
903 0.0
904 }
905 }
906 TsValue::Number(n) => *n,
907 TsValue::String(s) => s.parse().unwrap_or(f64::NAN),
908 TsValue::Object(_) => f64::NAN,
909 TsValue::Array(_) => {
910 if let TsValue::Array(arr) = self {
911 if arr.is_empty() { 0.0 } else { f64::NAN }
912 }
913 else {
914 f64::NAN
915 }
916 }
917 TsValue::Function(_) => f64::NAN,
918 TsValue::Error(_) => f64::NAN,
919 TsValue::Union(values) => {
920 if values.is_empty() {
921 0.0
922 }
923 else {
924 values[0].to_number()
925 }
926 }
927 TsValue::Generic(_, _) => f64::NAN,
928 TsValue::Symbol(_) => f64::NAN,
929 TsValue::BigInt(bi) => *bi as f64,
930 TsValue::Date(d) => *d as f64,
931 TsValue::RegExp(_) => f64::NAN,
932 TsValue::Map(_) => f64::NAN,
933 TsValue::Set(_) => f64::NAN,
934 TsValue::Promise(_) => f64::NAN,
935 TsValue::Iterable(_) => f64::NAN,
936 TsValue::Conditional(_) => f64::NAN,
937 TsValue::Mapped(_) => f64::NAN,
938 TsValue::TemplateLiteral(_) => f64::NAN,
939 TsValue::KeyOf(_) => f64::NAN,
940 TsValue::TypeOf(_) => f64::NAN,
941 TsValue::IndexedAccess { .. } => f64::NAN,
942 TsValue::Tuple(_) => f64::NAN,
943 TsValue::Readonly(_) => f64::NAN,
944 TsValue::Nullable(_) => f64::NAN,
945 TsValue::NonNullable(_) => f64::NAN,
946 TsValue::Infer { .. } => f64::NAN,
947 TsValue::FunctionType { .. } => f64::NAN,
948 TsValue::ConstructorType { .. } => f64::NAN,
949 TsValue::ThisType => f64::NAN,
950 TsValue::Never => f64::NAN,
951 TsValue::Unknown => f64::NAN,
952 TsValue::Any => f64::NAN,
953 TsValue::Void => f64::NAN,
954 }
955 }
956
957 pub fn to_string(&self) -> String {
959 match self {
960 TsValue::Undefined => "undefined".to_string(),
961 TsValue::Null => "null".to_string(),
962 TsValue::Boolean(b) => b.to_string(),
963 TsValue::Number(n) => n.to_string(),
964 TsValue::String(s) => s.clone(),
965 TsValue::Object(_) => "[object Object]".to_string(),
966 TsValue::Array(_) => {
967 if let TsValue::Array(arr) = self {
968 let elements: Vec<String> = arr.iter().map(|v| v.to_string()).collect();
969 format!("[{}]", elements.join(", "))
970 }
971 else {
972 "[object Array]".to_string()
973 }
974 }
975 TsValue::Function(_) => "[Function]".to_string(),
976 TsValue::Error(s) => format!("Error: {}", s),
977 TsValue::Union(values) => {
978 let elements: Vec<String> = values.iter().map(|v| v.to_string()).collect();
979 format!("Union({})", elements.join(", "))
980 }
981 TsValue::Generic(name, args) => {
982 let args_str: Vec<String> = args.iter().map(|v| v.to_string()).collect();
983 format!("{}<{}>", name, args_str.join(", "))
984 }
985 TsValue::Symbol(s) => format!("Symbol({})", s),
986 TsValue::BigInt(bi) => bi.to_string(),
987 TsValue::Date(d) => format!("Date({})", d),
988 TsValue::RegExp(pattern) => format!("/{}/", pattern),
989 TsValue::Map(entries) => {
990 let entries_str: Vec<String> =
991 entries.iter().map(|(k, v)| format!("{}: {}", k.to_string(), v.to_string())).collect();
992 format!("Map({})", entries_str.join(", "))
993 }
994 TsValue::Set(values) => {
995 let values_str: Vec<String> = values.iter().map(|v| v.to_string()).collect();
996 format!("Set({})", values_str.join(", "))
997 }
998 TsValue::Promise(value) => format!("Promise<{}>", value.to_string()),
999 TsValue::Iterable(_) => "[object Iterable]".to_string(),
1000 TsValue::Conditional(cond) => {
1001 format!(
1002 "{} extends {} ? {} : {}",
1003 cond.check_type.to_string(),
1004 cond.extends_type.to_string(),
1005 cond.true_type.to_string(),
1006 cond.false_type.to_string()
1007 )
1008 }
1009 TsValue::Mapped(mapped) => {
1010 let modifier = if mapped.key_modifier.readonly { "readonly " } else { "" };
1011 let optional = if mapped.key_modifier.optional { "?" } else { "" };
1012 format!(
1013 "{{ {}[{} in {}]{}: {} }}",
1014 modifier,
1015 mapped.type_param,
1016 mapped.constraint.to_string(),
1017 optional,
1018 mapped.value_type.to_string()
1019 )
1020 }
1021 TsValue::TemplateLiteral(tpl) => {
1022 let parts: Vec<String> = tpl
1023 .parts
1024 .iter()
1025 .map(|p| match p {
1026 TemplateLiteralPart::String(s) => s.clone(),
1027 TemplateLiteralPart::Type(ty) => format!("${{{}}}", ty.to_string()),
1028 TemplateLiteralPart::Number => "${number}".to_string(),
1029 TemplateLiteralPart::StringType => "${string}".to_string(),
1030 TemplateLiteralPart::BigInt => "${bigint}".to_string(),
1031 TemplateLiteralPart::Union(types) => {
1032 let types_str: Vec<String> = types.iter().map(|t| t.to_string()).collect();
1033 format!("${{{}}}", types_str.join(" | "))
1034 }
1035 })
1036 .collect();
1037 format!("`{}`", parts.join(""))
1038 }
1039 TsValue::KeyOf(ty) => format!("keyof {}", ty.to_string()),
1040 TsValue::TypeOf(ty) => format!("typeof {}", ty.to_string()),
1041 TsValue::IndexedAccess { object_type, index_type } => {
1042 format!("{}[{}]", object_type.to_string(), index_type.to_string())
1043 }
1044 TsValue::Tuple(elements) => {
1045 let elements_str: Vec<String> = elements.iter().map(|e| e.to_string()).collect();
1046 format!("[{}]", elements_str.join(", "))
1047 }
1048 TsValue::Readonly(ty) => format!("readonly {}", ty.to_string()),
1049 TsValue::Nullable(ty) => format!("{} | null", ty.to_string()),
1050 TsValue::NonNullable(ty) => format!("NonNullable<{}>", ty.to_string()),
1051 TsValue::Infer { type_param, .. } => format!("infer {}", type_param),
1052 TsValue::FunctionType { params, return_type } => {
1053 let params_str: Vec<String> = params.iter().map(|(name, ty)| format!("{}: {}", name, ty.to_string())).collect();
1054 format!("({}) => {}", params_str.join(", "), return_type.to_string())
1055 }
1056 TsValue::ConstructorType { params, return_type } => {
1057 let params_str: Vec<String> = params.iter().map(|(name, ty)| format!("{}: {}", name, ty.to_string())).collect();
1058 format!("new ({}) => {}", params_str.join(", "), return_type.to_string())
1059 }
1060 TsValue::ThisType => "this".to_string(),
1061 TsValue::Never => "never".to_string(),
1062 TsValue::Unknown => "unknown".to_string(),
1063 TsValue::Any => "any".to_string(),
1064 TsValue::Void => "void".to_string(),
1065 }
1066 }
1067
1068 pub fn is_assignable_to(&self, target: &TsValue) -> bool {
1070 match (self, target) {
1072 (TsValue::Any, _) | (_, TsValue::Any) => true,
1073 (TsValue::Unknown, _) => false,
1074 (_, TsValue::Unknown) => true,
1075 (TsValue::Never, _) => true,
1076 (_, TsValue::Never) => false,
1077 (TsValue::Void, TsValue::Void) => true,
1078 (TsValue::Void, _) | (_, TsValue::Void) => false,
1079 (TsValue::Null, TsValue::Null) => true,
1080 (TsValue::Undefined, TsValue::Undefined) => true,
1081 (TsValue::Boolean(_), TsValue::Boolean(_)) => true,
1082 (TsValue::Number(_), TsValue::Number(_)) => true,
1083 (TsValue::String(_), TsValue::String(_)) => true,
1084 (TsValue::BigInt(a), TsValue::BigInt(b)) => a == b,
1085 (TsValue::ThisType, TsValue::ThisType) => true,
1086 (TsValue::Nullable(_), TsValue::Null) => true,
1088 (TsValue::Nullable(inner), target) => inner.is_assignable_to(target),
1089 (source, TsValue::Nullable(inner)) => source.is_null() || source.is_assignable_to(inner),
1090 (TsValue::NonNullable(inner), target) => !self.is_null() && inner.is_assignable_to(target),
1092 (source, TsValue::NonNullable(inner)) => !source.is_null() && source.is_assignable_to(inner),
1093 (TsValue::Union(types), target) => types.iter().all(|t| t.is_assignable_to(target)),
1095 (source, TsValue::Union(types)) => types.iter().any(|t| source.is_assignable_to(t)),
1096 (TsValue::Conditional(cond), target) => {
1098 cond.true_type.is_assignable_to(target) && cond.false_type.is_assignable_to(target)
1099 }
1100 (source, TsValue::Conditional(cond)) => {
1101 if source.is_assignable_to(&cond.extends_type) {
1102 source.is_assignable_to(&cond.true_type)
1103 }
1104 else {
1105 source.is_assignable_to(&cond.false_type)
1106 }
1107 }
1108 _ => self == target,
1110 }
1111 }
1112
1113 pub fn get_property_keys(&self) -> Vec<String> {
1115 match self {
1116 TsValue::Object(props) => props.keys().cloned().collect(),
1117 TsValue::Tuple(elements) => (0..elements.len()).map(|i| i.to_string()).collect(),
1118 TsValue::Array(_) => vec!["length".to_string(), "push".to_string(), "pop".to_string()],
1119 TsValue::String(_) => vec!["length".to_string(), "charAt".to_string(), "concat".to_string(), "indexOf".to_string()],
1120 TsValue::Mapped(mapped) => {
1121 if let TsValue::KeyOf(inner) = mapped.constraint.as_ref() {
1122 inner.get_property_keys()
1123 }
1124 else {
1125 Vec::new()
1126 }
1127 }
1128 TsValue::Nullable(inner) => inner.get_property_keys(),
1129 TsValue::NonNullable(inner) => inner.get_property_keys(),
1130 TsValue::Union(types) => {
1131 let mut keys = Vec::new();
1132 for ty in types {
1133 for key in ty.get_property_keys() {
1134 if !keys.contains(&key) {
1135 keys.push(key);
1136 }
1137 }
1138 }
1139 keys
1140 }
1141 _ => Vec::new(),
1142 }
1143 }
1144
1145 pub fn get_property_type(&self, key: &str) -> Option<TsValue> {
1147 match self {
1148 TsValue::Object(props) => props.get(key).cloned(),
1149 TsValue::Tuple(elements) => {
1150 if let Ok(index) = key.parse::<usize>() {
1151 elements.get(index).cloned()
1152 }
1153 else {
1154 None
1155 }
1156 }
1157 TsValue::Array(_) => match key {
1158 "length" => Some(TsValue::Number(0.0)),
1159 _ => None,
1160 },
1161 TsValue::String(_) => match key {
1162 "length" => Some(TsValue::Number(0.0)),
1163 _ => None,
1164 },
1165 TsValue::IndexedAccess { object_type, index_type } => {
1166 if let TsValue::String(key_str) = index_type.as_ref() {
1167 object_type.get_property_type(key_str)
1168 }
1169 else {
1170 None
1171 }
1172 }
1173 TsValue::Nullable(inner) => inner.get_property_type(key),
1174 TsValue::NonNullable(inner) => inner.get_property_type(key),
1175 TsValue::Union(types) => {
1176 let results: Vec<TsValue> = types.iter().filter_map(|t| t.get_property_type(key)).collect();
1177 if results.is_empty() {
1178 None
1179 }
1180 else if results.len() == 1 {
1181 results.into_iter().next()
1182 }
1183 else {
1184 Some(TsValue::Union(results))
1185 }
1186 }
1187 _ => None,
1188 }
1189 }
1190
1191 pub fn evaluate_conditional(&self, check_type: &TsValue, extends_type: &TsValue) -> Option<bool> {
1193 match self {
1194 TsValue::Conditional(cond) => Some(check_type.is_assignable_to(&cond.extends_type)),
1195 _ => match extends_type {
1196 TsValue::Any => Some(true),
1197 TsValue::Unknown => Some(true),
1198 TsValue::Never => Some(false),
1199 TsValue::Union(types) => {
1200 let results: Vec<bool> = types.iter().filter_map(|t| self.evaluate_conditional(check_type, t)).collect();
1201 Some(results.iter().any(|&r| r))
1202 }
1203 _ => Some(check_type.is_assignable_to(extends_type)),
1204 },
1205 }
1206 }
1207
1208 pub fn infer_type_params(&self, target: &TsValue) -> InferenceResult {
1210 match (self, target) {
1212 (TsValue::Boolean(_), TsValue::Boolean(_))
1213 | (TsValue::Number(_), TsValue::Number(_))
1214 | (TsValue::String(_), TsValue::String(_)) => {
1215 return InferenceResult::success(HashMap::new());
1216 }
1217 _ if self == target => {
1218 return InferenceResult::success(HashMap::new());
1219 }
1220 _ => {}
1221 }
1222
1223 match (self, target) {
1224 (TsValue::Infer { type_param, constraint }, target) => {
1226 if let Some(constraint_ty) = constraint {
1227 if !target.is_assignable_to(constraint_ty) {
1228 return InferenceResult::failure();
1229 }
1230 }
1231 let mut inferred = HashMap::new();
1232 inferred.insert(type_param.clone(), target.clone());
1233 InferenceResult::success(inferred)
1234 }
1235 (TsValue::Generic(name1, args1), TsValue::Generic(name2, args2)) => {
1237 if name1 != name2 || args1.len() != args2.len() {
1238 return InferenceResult::failure();
1239 }
1240 let mut result = InferenceResult::success(HashMap::new());
1241 for (a1, a2) in args1.iter().zip(args2.iter()) {
1242 let sub_result = a1.infer_type_params(a2);
1243 result = result.merge(sub_result);
1244 }
1245 result
1246 }
1247 (TsValue::Union(types1), TsValue::Union(types2)) => {
1249 if types1.len() != types2.len() {
1250 return InferenceResult::failure();
1251 }
1252 let mut result = InferenceResult::success(HashMap::new());
1253 for (t1, t2) in types1.iter().zip(types2.iter()) {
1254 let sub_result = t1.infer_type_params(t2);
1255 result = result.merge(sub_result);
1256 }
1257 result
1258 }
1259 (TsValue::Tuple(elements1), TsValue::Tuple(elements2)) => {
1261 if elements1.len() != elements2.len() {
1262 return InferenceResult::failure();
1263 }
1264 let mut result = InferenceResult::success(HashMap::new());
1265 for (e1, e2) in elements1.iter().zip(elements2.iter()) {
1266 let sub_result = e1.infer_type_params(e2);
1267 result = result.merge(sub_result);
1268 }
1269 result
1270 }
1271 (TsValue::Object(props1), TsValue::Object(props2)) => {
1273 let mut result = InferenceResult::success(HashMap::new());
1274 for (key, value1) in props1 {
1275 if let Some(value2) = props2.get(key) {
1276 let sub_result = value1.infer_type_params(value2);
1277 result = result.merge(sub_result);
1278 }
1279 }
1280 result
1281 }
1282 (
1284 TsValue::FunctionType { params: params1, return_type: ret1 },
1285 TsValue::FunctionType { params: params2, return_type: ret2 },
1286 ) => {
1287 if params1.len() != params2.len() {
1288 return InferenceResult::failure();
1289 }
1290 let mut result = ret1.infer_type_params(ret2);
1291 for ((_, ty1), (_, ty2)) in params1.iter().zip(params2.iter()) {
1292 let sub_result = ty1.infer_type_params(ty2);
1293 result = result.merge(sub_result);
1294 }
1295 result
1296 }
1297 (TsValue::Nullable(inner1), TsValue::Nullable(inner2)) => inner1.infer_type_params(inner2),
1299 (TsValue::NonNullable(inner1), TsValue::NonNullable(inner2)) => inner1.infer_type_params(inner2),
1300 (TsValue::Readonly(inner1), TsValue::Readonly(inner2)) => inner1.infer_type_params(inner2),
1301 (TsValue::Promise(inner1), TsValue::Promise(inner2)) => inner1.infer_type_params(inner2),
1302 (TsValue::Array(elements1), TsValue::Array(elements2)) => {
1304 if elements1.len() != elements2.len() {
1305 return InferenceResult::failure();
1306 }
1307 let mut result = InferenceResult::success(HashMap::new());
1308 for (e1, e2) in elements1.iter().zip(elements2.iter()) {
1309 let sub_result = e1.infer_type_params(e2);
1310 result = result.merge(sub_result);
1311 }
1312 result
1313 }
1314 _ => InferenceResult::failure(),
1316 }
1317 }
1318
1319 pub fn substitute_type_params(&self, substitutions: &HashMap<String, TsValue>) -> TsValue {
1321 match self {
1322 TsValue::Generic(name, args) => {
1323 if let Some(substituted) = substitutions.get(name) {
1324 substituted.clone()
1325 }
1326 else {
1327 TsValue::Generic(name.clone(), args.iter().map(|a| a.substitute_type_params(substitutions)).collect())
1328 }
1329 }
1330 TsValue::Union(types) => TsValue::Union(types.iter().map(|t| t.substitute_type_params(substitutions)).collect()),
1331 TsValue::Tuple(elements) => {
1332 TsValue::Tuple(elements.iter().map(|e| e.substitute_type_params(substitutions)).collect())
1333 }
1334 TsValue::Array(elements) => {
1335 TsValue::Array(elements.iter().map(|e| e.substitute_type_params(substitutions)).collect())
1336 }
1337 TsValue::Object(props) => {
1338 TsValue::Object(props.iter().map(|(k, v)| (k.clone(), v.substitute_type_params(substitutions))).collect())
1339 }
1340 TsValue::Nullable(inner) => TsValue::Nullable(Box::new(inner.substitute_type_params(substitutions))),
1341 TsValue::NonNullable(inner) => TsValue::NonNullable(Box::new(inner.substitute_type_params(substitutions))),
1342 TsValue::Readonly(inner) => TsValue::Readonly(Box::new(inner.substitute_type_params(substitutions))),
1343 TsValue::Promise(inner) => TsValue::Promise(Box::new(inner.substitute_type_params(substitutions))),
1344 TsValue::KeyOf(inner) => TsValue::KeyOf(Box::new(inner.substitute_type_params(substitutions))),
1345 TsValue::TypeOf(inner) => TsValue::TypeOf(Box::new(inner.substitute_type_params(substitutions))),
1346 TsValue::Conditional(cond) => TsValue::Conditional(Conditional {
1347 check_type: Box::new(cond.check_type.substitute_type_params(substitutions)),
1348 extends_type: Box::new(cond.extends_type.substitute_type_params(substitutions)),
1349 true_type: Box::new(cond.true_type.substitute_type_params(substitutions)),
1350 false_type: Box::new(cond.false_type.substitute_type_params(substitutions)),
1351 modifier: cond.modifier.clone(),
1352 }),
1353 TsValue::Mapped(mapped) => TsValue::Mapped(Mapped {
1354 type_param: mapped.type_param.clone(),
1355 constraint: Box::new(mapped.constraint.substitute_type_params(substitutions)),
1356 value_type: Box::new(mapped.value_type.substitute_type_params(substitutions)),
1357 key_modifier: mapped.key_modifier.clone(),
1358 constraint_type: mapped.constraint_type.clone(),
1359 }),
1360 TsValue::TemplateLiteral(tpl) => TsValue::TemplateLiteral(TemplateLiteral {
1361 parts: tpl
1362 .parts
1363 .iter()
1364 .map(|p| match p {
1365 TemplateLiteralPart::String(s) => TemplateLiteralPart::String(s.clone()),
1366 TemplateLiteralPart::Type(ty) => {
1367 TemplateLiteralPart::Type(Box::new(ty.substitute_type_params(substitutions)))
1368 }
1369 TemplateLiteralPart::Number => TemplateLiteralPart::Number,
1370 TemplateLiteralPart::StringType => TemplateLiteralPart::StringType,
1371 TemplateLiteralPart::BigInt => TemplateLiteralPart::BigInt,
1372 TemplateLiteralPart::Union(types) => {
1373 TemplateLiteralPart::Union(types.iter().map(|t| t.substitute_type_params(substitutions)).collect())
1374 }
1375 })
1376 .collect(),
1377 }),
1378 TsValue::IndexedAccess { object_type, index_type } => TsValue::IndexedAccess {
1379 object_type: Box::new(object_type.substitute_type_params(substitutions)),
1380 index_type: Box::new(index_type.substitute_type_params(substitutions)),
1381 },
1382 TsValue::FunctionType { params, return_type } => TsValue::FunctionType {
1383 params: params.iter().map(|(name, ty)| (name.clone(), ty.substitute_type_params(substitutions))).collect(),
1384 return_type: Box::new(return_type.substitute_type_params(substitutions)),
1385 },
1386 TsValue::ConstructorType { params, return_type } => TsValue::ConstructorType {
1387 params: params.iter().map(|(name, ty)| (name.clone(), ty.substitute_type_params(substitutions))).collect(),
1388 return_type: Box::new(return_type.substitute_type_params(substitutions)),
1389 },
1390 TsValue::Infer { type_param, constraint } => TsValue::Infer {
1391 type_param: type_param.clone(),
1392 constraint: constraint.as_ref().map(|c| Box::new(c.substitute_type_params(substitutions))),
1393 },
1394 _ => self.clone(),
1395 }
1396 }
1397
1398 pub fn intersection_with(&self, other: &TsValue) -> TsValue {
1406 match (self, other) {
1407 (TsValue::Any, _) | (_, TsValue::Any) => other.clone(),
1409 (TsValue::Unknown, _) | (_, TsValue::Unknown) => TsValue::Unknown,
1410 (TsValue::Never, _) | (_, TsValue::Never) => TsValue::Never,
1411 (TsValue::Void, _) | (_, TsValue::Void) => TsValue::Void,
1412 (a, b) if a == b => a.clone(),
1413
1414 (TsValue::Union(types1), TsValue::Union(types2)) => {
1416 let mut result = Vec::new();
1417 for t1 in types1 {
1418 for t2 in types2 {
1419 let intersection = t1.intersection_with(t2);
1420 if !intersection.is_never() {
1421 result.push(intersection);
1422 }
1423 }
1424 }
1425 if result.is_empty() {
1426 TsValue::Never
1427 }
1428 else if result.len() == 1 {
1429 result[0].clone()
1430 }
1431 else {
1432 TsValue::Union(result)
1433 }
1434 }
1435 (TsValue::Union(types), other) => {
1436 let mut result = Vec::new();
1437 for t in types {
1438 let intersection = t.intersection_with(other);
1439 if !intersection.is_never() {
1440 result.push(intersection);
1441 }
1442 }
1443 if result.is_empty() {
1444 TsValue::Never
1445 }
1446 else if result.len() == 1 {
1447 result[0].clone()
1448 }
1449 else {
1450 TsValue::Union(result)
1451 }
1452 }
1453 (other, TsValue::Union(types)) => {
1454 let mut result = Vec::new();
1455 for t in types {
1456 let intersection = other.intersection_with(t);
1457 if !intersection.is_never() {
1458 result.push(intersection);
1459 }
1460 }
1461 if result.is_empty() {
1462 TsValue::Never
1463 }
1464 else if result.len() == 1 {
1465 result[0].clone()
1466 }
1467 else {
1468 TsValue::Union(result)
1469 }
1470 }
1471
1472 (TsValue::Object(props1), TsValue::Object(props2)) => {
1474 let mut result = HashMap::new();
1475 for (key, value1) in props1 {
1476 if let Some(value2) = props2.get(key) {
1477 let intersection = value1.intersection_with(value2);
1478 if !intersection.is_never() {
1479 result.insert(key.clone(), intersection);
1480 }
1481 }
1482 }
1483 TsValue::Object(result)
1484 }
1485
1486 _ => TsValue::Never,
1488 }
1489 }
1490
1491 pub fn difference_with(&self, other: &TsValue) -> TsValue {
1499 match (self, other) {
1500 (TsValue::Any, TsValue::Any) => TsValue::Never,
1502 (TsValue::Any, _) => TsValue::Any,
1503 (_, TsValue::Any) => TsValue::Never,
1504 (TsValue::Unknown, _) => TsValue::Unknown,
1505 (_, TsValue::Unknown) => TsValue::Never,
1506 (TsValue::Never, _) => TsValue::Never,
1507 (_, TsValue::Never) => self.clone(),
1508 (TsValue::Void, _) => TsValue::Void,
1509 (_, TsValue::Void) => self.clone(),
1510 (a, b) if a == b => TsValue::Never,
1511
1512 (TsValue::Union(types), other) => {
1514 let mut result = Vec::new();
1515 for t in types {
1516 let difference = t.difference_with(other);
1517 if !difference.is_never() {
1518 result.push(difference);
1519 }
1520 }
1521 if result.is_empty() {
1522 TsValue::Never
1523 }
1524 else if result.len() == 1 {
1525 result[0].clone()
1526 }
1527 else {
1528 TsValue::Union(result)
1529 }
1530 }
1531
1532 _ => self.clone(),
1534 }
1535 }
1536
1537 pub fn apply_mapped_type(&self, mapped_type: &Mapped) -> TsValue {
1545 match self {
1546 TsValue::Object(props) => {
1547 let mut result = HashMap::new();
1548 for (key, _value) in props {
1549 let mut substitutions = HashMap::new();
1551 substitutions.insert(mapped_type.type_param.clone(), TsValue::String(key.clone()));
1552 let mapped_value = mapped_type.value_type.substitute_type_params(&substitutions);
1553 result.insert(key.clone(), mapped_value);
1554 }
1555 TsValue::Object(result)
1556 }
1557 _ => TsValue::Never,
1558 }
1559 }
1560
1561 pub fn is_primitive(&self) -> bool {
1566 matches!(
1567 self,
1568 TsValue::Undefined
1569 | TsValue::Null
1570 | TsValue::Boolean(_)
1571 | TsValue::Number(_)
1572 | TsValue::String(_)
1573 | TsValue::Symbol(_)
1574 | TsValue::BigInt(_)
1575 )
1576 }
1577
1578 pub fn is_complex(&self) -> bool {
1583 matches!(
1584 self,
1585 TsValue::Object(_)
1586 | TsValue::Array(_)
1587 | TsValue::Function(_)
1588 | TsValue::Union(_)
1589 | TsValue::Tuple(_)
1590 | TsValue::Map(_)
1591 | TsValue::Set(_)
1592 | TsValue::Promise(_)
1593 )
1594 }
1595
1596 pub fn type_name(&self) -> String {
1601 match self {
1602 TsValue::Undefined => "undefined".to_string(),
1603 TsValue::Null => "null".to_string(),
1604 TsValue::Boolean(_) => "boolean".to_string(),
1605 TsValue::Number(_) => "number".to_string(),
1606 TsValue::String(_) => "string".to_string(),
1607 TsValue::Object(_) => "object".to_string(),
1608 TsValue::Array(_) => "array".to_string(),
1609 TsValue::Function(_) => "function".to_string(),
1610 TsValue::Error(_) => "error".to_string(),
1611 TsValue::Union(_) => "union".to_string(),
1612 TsValue::Generic(name, _) => name.clone(),
1613 TsValue::Symbol(_) => "symbol".to_string(),
1614 TsValue::BigInt(_) => "bigint".to_string(),
1615 TsValue::Date(_) => "date".to_string(),
1616 TsValue::RegExp(_) => "regexp".to_string(),
1617 TsValue::Map(_) => "map".to_string(),
1618 TsValue::Set(_) => "set".to_string(),
1619 TsValue::Promise(_) => "promise".to_string(),
1620 TsValue::Iterable(_) => "iterable".to_string(),
1621 TsValue::Conditional(_) => "conditional".to_string(),
1622 TsValue::Mapped(_) => "mapped".to_string(),
1623 TsValue::TemplateLiteral(_) => "template_literal".to_string(),
1624 TsValue::KeyOf(_) => "keyof".to_string(),
1625 TsValue::TypeOf(_) => "typeof".to_string(),
1626 TsValue::IndexedAccess { .. } => "indexed_access".to_string(),
1627 TsValue::Tuple(_) => "tuple".to_string(),
1628 TsValue::Readonly(_) => "readonly".to_string(),
1629 TsValue::Nullable(_) => "nullable".to_string(),
1630 TsValue::NonNullable(_) => "non_nullable".to_string(),
1631 TsValue::Infer { type_param, .. } => format!("infer {}", type_param),
1632 TsValue::FunctionType { .. } => "function_type".to_string(),
1633 TsValue::ConstructorType { .. } => "constructor_type".to_string(),
1634 TsValue::ThisType => "this".to_string(),
1635 TsValue::Never => "never".to_string(),
1636 TsValue::Unknown => "unknown".to_string(),
1637 TsValue::Any => "any".to_string(),
1638 TsValue::Void => "void".to_string(),
1639 }
1640 }
1641
1642 pub fn simplify(&self) -> TsValue {
1647 match self {
1648 TsValue::Union(types) => {
1649 let filtered: Vec<TsValue> = types.iter().map(|t| t.simplify()).filter(|t| !t.is_never()).collect();
1651
1652 let mut unique = Vec::new();
1654 for t in filtered {
1655 if !unique.iter().any(|u| u == &t) {
1656 unique.push(t);
1657 }
1658 }
1659
1660 if unique.is_empty() {
1661 TsValue::Never
1662 }
1663 else if unique.len() == 1 {
1664 unique[0].clone()
1665 }
1666 else {
1667 TsValue::Union(unique)
1668 }
1669 }
1670 TsValue::Nullable(inner) => {
1671 let simplified = inner.simplify();
1672 if simplified.is_never() { TsValue::Never } else { TsValue::Nullable(Box::new(simplified)) }
1673 }
1674 TsValue::NonNullable(inner) => {
1675 let simplified = inner.simplify();
1676 if simplified.is_never() { TsValue::Never } else { TsValue::NonNullable(Box::new(simplified)) }
1677 }
1678 TsValue::Readonly(inner) => {
1679 let simplified = inner.simplify();
1680 TsValue::Readonly(Box::new(simplified))
1681 }
1682 TsValue::Promise(inner) => {
1683 let simplified = inner.simplify();
1684 TsValue::Promise(Box::new(simplified))
1685 }
1686 TsValue::Array(elements) => {
1687 let simplified: Vec<TsValue> = elements.iter().map(|e| e.simplify()).collect();
1688 TsValue::Array(simplified)
1689 }
1690 TsValue::Object(props) => {
1691 let simplified: HashMap<String, TsValue> = props.iter().map(|(k, v)| (k.clone(), v.simplify())).collect();
1692 TsValue::Object(simplified)
1693 }
1694 TsValue::Tuple(elements) => {
1695 let simplified: Vec<TsValue> = elements.iter().map(|e| e.simplify()).collect();
1696 TsValue::Tuple(simplified)
1697 }
1698 TsValue::Conditional(cond) => TsValue::Conditional(Conditional {
1699 check_type: Box::new(cond.check_type.simplify()),
1700 extends_type: Box::new(cond.extends_type.simplify()),
1701 true_type: Box::new(cond.true_type.simplify()),
1702 false_type: Box::new(cond.false_type.simplify()),
1703 modifier: cond.modifier.clone(),
1704 }),
1705 TsValue::Mapped(mapped) => TsValue::Mapped(Mapped {
1706 type_param: mapped.type_param.clone(),
1707 constraint: Box::new(mapped.constraint.simplify()),
1708 value_type: Box::new(mapped.value_type.simplify()),
1709 key_modifier: mapped.key_modifier.clone(),
1710 constraint_type: mapped.constraint_type.clone(),
1711 }),
1712 TsValue::TemplateLiteral(tpl) => TsValue::TemplateLiteral(TemplateLiteral {
1713 parts: tpl
1714 .parts
1715 .iter()
1716 .map(|p| match p {
1717 TemplateLiteralPart::String(s) => TemplateLiteralPart::String(s.clone()),
1718 TemplateLiteralPart::Type(ty) => TemplateLiteralPart::Type(Box::new(ty.simplify())),
1719 TemplateLiteralPart::Number => TemplateLiteralPart::Number,
1720 TemplateLiteralPart::StringType => TemplateLiteralPart::StringType,
1721 TemplateLiteralPart::BigInt => TemplateLiteralPart::BigInt,
1722 TemplateLiteralPart::Union(types) => {
1723 TemplateLiteralPart::Union(types.iter().map(|t| t.simplify()).collect())
1724 }
1725 })
1726 .collect(),
1727 }),
1728 TsValue::IndexedAccess { object_type, index_type } => TsValue::IndexedAccess {
1729 object_type: Box::new(object_type.simplify()),
1730 index_type: Box::new(index_type.simplify()),
1731 },
1732 TsValue::FunctionType { params, return_type } => TsValue::FunctionType {
1733 params: params.iter().map(|(name, ty)| (name.clone(), ty.simplify())).collect(),
1734 return_type: Box::new(return_type.simplify()),
1735 },
1736 TsValue::ConstructorType { params, return_type } => TsValue::ConstructorType {
1737 params: params.iter().map(|(name, ty)| (name.clone(), ty.simplify())).collect(),
1738 return_type: Box::new(return_type.simplify()),
1739 },
1740 _ => self.clone(),
1741 }
1742 }
1743
1744 pub fn intersect(&self, other: &TsValue) -> TsValue {
1746 match (self, other) {
1747 (TsValue::Any, _) | (_, TsValue::Any) => TsValue::Any,
1748 (TsValue::Never, _) | (_, TsValue::Never) => TsValue::Never,
1749 (TsValue::Object(props1), TsValue::Object(props2)) => {
1750 let mut merged = props1.clone();
1751 for (key, value) in props2 {
1752 merged.insert(key.clone(), value.clone());
1753 }
1754 TsValue::Object(merged)
1755 }
1756 (TsValue::Union(types1), TsValue::Union(types2)) => {
1757 let mut result = Vec::new();
1758 for t1 in types1 {
1759 for t2 in types2 {
1760 result.push(t1.intersect(t2));
1761 }
1762 }
1763 TsValue::Union(result)
1764 }
1765 (TsValue::Union(types), other) => {
1766 let result: Vec<TsValue> = types.iter().map(|t| t.intersect(other)).collect();
1767 TsValue::Union(result)
1768 }
1769 (other, TsValue::Union(types)) => {
1770 let result: Vec<TsValue> = types.iter().map(|t| other.intersect(t)).collect();
1771 TsValue::Union(result)
1772 }
1773 _ => {
1774 if self.is_assignable_to(other) {
1775 self.clone()
1776 }
1777 else if other.is_assignable_to(self) {
1778 other.clone()
1779 }
1780 else {
1781 TsValue::Never
1782 }
1783 }
1784 }
1785 }
1786
1787 pub fn difference(&self, other: &TsValue) -> TsValue {
1789 match (self, other) {
1790 (TsValue::Any, TsValue::Any) => TsValue::Never,
1791 (TsValue::Any, _) => TsValue::Any,
1792 (_, TsValue::Any) => TsValue::Never,
1793 (TsValue::Never, _) => TsValue::Never,
1794 (_, TsValue::Never) => self.clone(),
1795 (TsValue::Object(props1), TsValue::Object(props2)) => {
1796 let mut result = props1.clone();
1797 for key in props2.keys() {
1798 result.remove(key);
1799 }
1800 TsValue::Object(result)
1801 }
1802 (TsValue::Union(types), other) => {
1803 let result: Vec<TsValue> =
1804 types.iter().map(|t| t.difference(other)).filter(|t| !matches!(t, TsValue::Never)).collect();
1805 if result.is_empty() {
1806 TsValue::Never
1807 }
1808 else if result.len() == 1 {
1809 result[0].clone()
1810 }
1811 else {
1812 TsValue::Union(result)
1813 }
1814 }
1815 _ => {
1816 if self.is_assignable_to(other) {
1817 TsValue::Never
1818 }
1819 else {
1820 self.clone()
1821 }
1822 }
1823 }
1824 }
1825
1826 pub fn is_literal(&self) -> bool {
1828 match self {
1829 TsValue::Boolean(_) | TsValue::Number(_) | TsValue::String(_) | TsValue::BigInt(_) => true,
1830 _ => false,
1831 }
1832 }
1833
1834 pub fn get_base_type(&self) -> TsValue {
1836 match self {
1837 TsValue::Nullable(inner) | TsValue::NonNullable(inner) | TsValue::Readonly(inner) => inner.get_base_type(),
1838 TsValue::Promise(inner) => TsValue::Promise(Box::new(inner.get_base_type())),
1839 TsValue::Array(elements) => {
1840 if elements.is_empty() {
1841 TsValue::Array(Vec::new())
1842 }
1843 else {
1844 TsValue::Array(vec![elements[0].get_base_type()])
1845 }
1846 }
1847 _ => self.clone(),
1848 }
1849 }
1850
1851 pub fn is_part_of_union(&self, union: &TsValue) -> bool {
1853 match union {
1854 TsValue::Union(types) => types.iter().any(|t| self.is_assignable_to(t) || t.is_assignable_to(self)),
1855 _ => self.is_assignable_to(union) || union.is_assignable_to(self),
1856 }
1857 }
1858
1859 pub fn resolve_keyof(&self) -> TsValue {
1861 match self {
1862 TsValue::Object(props) => {
1863 let keys: Vec<TsValue> = props.keys().map(|k| TsValue::String(k.clone())).collect();
1864 if keys.is_empty() {
1865 TsValue::Never
1866 }
1867 else if keys.len() == 1 {
1868 keys[0].clone()
1869 }
1870 else {
1871 TsValue::Union(keys)
1872 }
1873 }
1874 TsValue::Array(_) => TsValue::Union(vec![
1875 TsValue::String("length".to_string()),
1876 TsValue::String("push".to_string()),
1877 TsValue::String("pop".to_string()),
1878 TsValue::String("shift".to_string()),
1879 TsValue::String("unshift".to_string()),
1880 TsValue::String("slice".to_string()),
1881 TsValue::String("splice".to_string()),
1882 TsValue::String("forEach".to_string()),
1883 TsValue::String("map".to_string()),
1884 TsValue::String("filter".to_string()),
1885 TsValue::String("reduce".to_string()),
1886 ]),
1887 TsValue::Tuple(elements) => {
1888 let mut keys = Vec::new();
1889 for (i, _) in elements.iter().enumerate() {
1890 keys.push(TsValue::String(i.to_string()));
1891 }
1892 keys.push(TsValue::String("length".to_string()));
1893 TsValue::Union(keys)
1894 }
1895 TsValue::Union(types) => {
1896 let mut all_keys = Vec::new();
1897 for ty in types {
1898 match ty.resolve_keyof() {
1899 TsValue::Union(keys) => all_keys.extend(keys),
1900 key => all_keys.push(key),
1901 }
1902 }
1903 if all_keys.is_empty() {
1904 TsValue::Never
1905 }
1906 else if all_keys.len() == 1 {
1907 all_keys[0].clone()
1908 }
1909 else {
1910 TsValue::Union(all_keys)
1911 }
1912 }
1913 TsValue::Nullable(inner) => inner.resolve_keyof(),
1914 TsValue::NonNullable(inner) => inner.resolve_keyof(),
1915 TsValue::Readonly(inner) => inner.resolve_keyof(),
1916 TsValue::Promise(_inner) => TsValue::Union(vec![
1917 TsValue::String("then".to_string()),
1918 TsValue::String("catch".to_string()),
1919 TsValue::String("finally".to_string()),
1920 ]),
1921 TsValue::KeyOf(inner) => inner.resolve_keyof(),
1922 _ => TsValue::Never,
1923 }
1924 }
1925
1926 pub fn resolve_indexed_access(&self) -> TsValue {
1928 match self {
1929 TsValue::IndexedAccess { object_type, index_type } => {
1930 let obj = object_type.resolve_indexed_access();
1931 let idx = index_type.resolve_indexed_access();
1932 match &idx {
1933 TsValue::String(key) => obj.get_property_type(key).unwrap_or(TsValue::Never),
1934 TsValue::Union(keys) => {
1935 let results: Vec<TsValue> = keys
1936 .iter()
1937 .filter_map(|k| if let TsValue::String(key) = k { obj.get_property_type(key) } else { None })
1938 .collect();
1939 if results.is_empty() {
1940 TsValue::Never
1941 }
1942 else if results.len() == 1 {
1943 results.into_iter().next().unwrap()
1944 }
1945 else {
1946 TsValue::Union(results)
1947 }
1948 }
1949 TsValue::KeyOf(inner) => {
1950 let keys = inner.resolve_keyof();
1951 TsValue::IndexedAccess { object_type: Box::new(obj), index_type: Box::new(keys) }
1952 .resolve_indexed_access()
1953 }
1954 _ => TsValue::Never,
1955 }
1956 }
1957 TsValue::Union(types) => {
1958 let resolved: Vec<TsValue> = types.iter().map(|t| t.resolve_indexed_access()).collect();
1959 TsValue::Union(resolved)
1960 }
1961 TsValue::Tuple(elements) => {
1962 let resolved: Vec<TsValue> = elements.iter().map(|e| e.resolve_indexed_access()).collect();
1963 TsValue::Tuple(resolved)
1964 }
1965 TsValue::Array(elements) => {
1966 let resolved: Vec<TsValue> = elements.iter().map(|e| e.resolve_indexed_access()).collect();
1967 TsValue::Array(resolved)
1968 }
1969 TsValue::Object(props) => {
1970 let resolved: HashMap<String, TsValue> =
1971 props.iter().map(|(k, v)| (k.clone(), v.resolve_indexed_access())).collect();
1972 TsValue::Object(resolved)
1973 }
1974 TsValue::Nullable(inner) => TsValue::Nullable(Box::new(inner.resolve_indexed_access())),
1975 TsValue::NonNullable(inner) => TsValue::NonNullable(Box::new(inner.resolve_indexed_access())),
1976 TsValue::Readonly(inner) => TsValue::Readonly(Box::new(inner.resolve_indexed_access())),
1977 TsValue::Promise(inner) => TsValue::Promise(Box::new(inner.resolve_indexed_access())),
1978 other => other.clone(),
1979 }
1980 }
1981
1982 pub fn resolve_mapped(&self) -> TsValue {
1984 match self {
1985 TsValue::Mapped(mapped) => {
1986 let keys_type = mapped.constraint.resolve_keyof();
1987 let keys = match keys_type {
1988 TsValue::Union(types) => types,
1989 TsValue::String(s) => vec![TsValue::String(s)],
1990 TsValue::Never => return TsValue::Object(HashMap::new()),
1991 _ => return self.clone(),
1992 };
1993 let mut props = HashMap::new();
1994 for key in keys {
1995 if let TsValue::String(key_str) = key {
1996 let mut substitutions = HashMap::new();
1997 substitutions.insert(mapped.type_param.clone(), TsValue::String(key_str.clone()));
1998 let value_type = mapped.value_type.substitute_type_params(&substitutions);
1999 props.insert(key_str, value_type);
2000 }
2001 }
2002 TsValue::Object(props)
2003 }
2004 TsValue::Union(types) => {
2005 let resolved: Vec<TsValue> = types.iter().map(|t| t.resolve_mapped()).collect();
2006 TsValue::Union(resolved)
2007 }
2008 TsValue::Tuple(elements) => {
2009 let resolved: Vec<TsValue> = elements.iter().map(|e| e.resolve_mapped()).collect();
2010 TsValue::Tuple(resolved)
2011 }
2012 TsValue::Array(elements) => {
2013 let resolved: Vec<TsValue> = elements.iter().map(|e| e.resolve_mapped()).collect();
2014 TsValue::Array(resolved)
2015 }
2016 TsValue::Object(props) => {
2017 let resolved: HashMap<String, TsValue> = props.iter().map(|(k, v)| (k.clone(), v.resolve_mapped())).collect();
2018 TsValue::Object(resolved)
2019 }
2020 TsValue::Nullable(inner) => TsValue::Nullable(Box::new(inner.resolve_mapped())),
2021 TsValue::NonNullable(inner) => TsValue::NonNullable(Box::new(inner.resolve_mapped())),
2022 TsValue::Readonly(inner) => TsValue::Readonly(Box::new(inner.resolve_mapped())),
2023 TsValue::Promise(inner) => TsValue::Promise(Box::new(inner.resolve_mapped())),
2024 other => other.clone(),
2025 }
2026 }
2027}
2028
2029#[derive(Debug, Clone)]
2031pub enum TsError {
2032 TypeError(String),
2034 ReferenceError(String),
2036 SyntaxError(String),
2038 RangeError(String),
2040 Other(String),
2042}
2043
2044impl std::fmt::Display for TsError {
2045 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2046 match self {
2047 TsError::TypeError(msg) => write!(f, "TypeError: {}", msg),
2048 TsError::ReferenceError(msg) => write!(f, "ReferenceError: {}", msg),
2049 TsError::SyntaxError(msg) => write!(f, "SyntaxError: {}", msg),
2050 TsError::RangeError(msg) => write!(f, "RangeError: {}", msg),
2051 TsError::Other(msg) => write!(f, "Error: {}", msg),
2052 }
2053 }
2054}
2055
2056pub trait ToTsValue {
2058 fn to_ts_value(&self) -> TsValue;
2060}
2061
2062impl ToTsValue for bool {
2063 fn to_ts_value(&self) -> TsValue {
2064 TsValue::Boolean(*self)
2065 }
2066}
2067
2068impl ToTsValue for f64 {
2069 fn to_ts_value(&self) -> TsValue {
2070 TsValue::Number(*self)
2071 }
2072}
2073
2074impl ToTsValue for i32 {
2075 fn to_ts_value(&self) -> TsValue {
2076 TsValue::Number(*self as f64)
2077 }
2078}
2079
2080impl ToTsValue for &str {
2081 fn to_ts_value(&self) -> TsValue {
2082 TsValue::String(self.to_string())
2083 }
2084}
2085
2086impl ToTsValue for String {
2087 fn to_ts_value(&self) -> TsValue {
2088 TsValue::String(self.clone())
2089 }
2090}
2091
2092impl<T: ToTsValue> ToTsValue for Vec<T> {
2093 fn to_ts_value(&self) -> TsValue {
2094 let values: Vec<TsValue> = self.iter().map(|v| v.to_ts_value()).collect();
2095 TsValue::Array(values)
2096 }
2097}
2098
2099impl<K: ToString, V: ToTsValue> ToTsValue for Vec<(K, V)> {
2100 fn to_ts_value(&self) -> TsValue {
2101 let mut map = HashMap::new();
2102 for (k, v) in self {
2103 map.insert(k.to_string(), v.to_ts_value());
2104 }
2105 TsValue::Object(map)
2106 }
2107}
2108
2109impl ToTsValue for i128 {
2110 fn to_ts_value(&self) -> TsValue {
2111 TsValue::BigInt(*self)
2112 }
2113}
2114
2115impl ToTsValue for i64 {
2116 fn to_ts_value(&self) -> TsValue {
2117 TsValue::Date(*self)
2118 }
2119}
2120
2121impl<T: ToTsValue> ToTsValue for Option<T> {
2122 fn to_ts_value(&self) -> TsValue {
2123 match self {
2124 Some(value) => value.to_ts_value(),
2125 None => TsValue::Null,
2126 }
2127 }
2128}
2129
2130impl<T: ToTsValue, E: ToString> ToTsValue for Result<T, E> {
2131 fn to_ts_value(&self) -> TsValue {
2132 match self {
2133 Ok(value) => value.to_ts_value(),
2134 Err(error) => TsValue::Error(error.to_string()),
2135 }
2136 }
2137}
2138
2139impl ToTsValue for std::collections::HashMap<String, TsValue> {
2140 fn to_ts_value(&self) -> TsValue {
2141 TsValue::Object(self.clone())
2142 }
2143}
2144
2145impl ToTsValue for std::collections::HashSet<TsValue> {
2146 fn to_ts_value(&self) -> TsValue {
2147 let values: Vec<TsValue> = self.iter().cloned().collect();
2148 TsValue::Set(values)
2149 }
2150}
2151
2152impl ToTsValue for std::collections::HashMap<TsValue, TsValue> {
2153 fn to_ts_value(&self) -> TsValue {
2154 let entries: Vec<(TsValue, TsValue)> = self.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
2155 TsValue::Map(entries)
2156 }
2157}
2158
2159unsafe impl Send for TsValue {}
2160
2161unsafe impl Sync for TsValue {}
2162
2163#[cfg(test)]
2164mod tests {
2165 use super::*;
2166
2167 #[test]
2168 fn test_conditional_type() {
2169 let check_type = TsValue::String("hello".to_string());
2170 let extends_type = TsValue::String("hello".to_string());
2171 let true_type = TsValue::Boolean(true);
2172 let false_type = TsValue::Boolean(false);
2173 let cond = Conditional::new(check_type, extends_type, true_type, false_type);
2174 let ts_cond = TsValue::Conditional(cond);
2175 assert!(ts_cond.is_conditional());
2176 }
2177
2178 #[test]
2179 fn test_mapped_type() {
2180 let constraint = TsValue::KeyOf(Box::new(TsValue::Object(HashMap::new())));
2181 let value_type = TsValue::String("value".to_string());
2182 let mapped = Mapped::new("K".to_string(), constraint, value_type);
2183 let ts_mapped = TsValue::Mapped(mapped);
2184 assert!(ts_mapped.is_mapped());
2185 }
2186
2187 #[test]
2188 fn test_template_literal() {
2189 let mut tpl = TemplateLiteral::new();
2190 tpl.push_string("hello".to_string());
2191 tpl.push_string_type();
2192 let ts_tpl = TsValue::TemplateLiteral(tpl);
2193 assert!(ts_tpl.is_template_literal());
2194 }
2195
2196 #[test]
2197 fn test_type_inference() {
2198 let infer_type = TsValue::Infer { type_param: "T".to_string(), constraint: None };
2199 let target = TsValue::String("hello".to_string());
2200 let result = infer_type.infer_type_params(&target);
2201 assert!(result.success);
2202 assert_eq!(result.inferred_types.get("T"), Some(&TsValue::String("hello".to_string())));
2203 }
2204
2205 #[test]
2206 fn test_keyof_resolution() {
2207 let mut props = HashMap::new();
2208 props.insert("name".to_string(), TsValue::String("".to_string()));
2209 props.insert("age".to_string(), TsValue::Number(0.0));
2210 let obj = TsValue::Object(props);
2211 let keyof = TsValue::KeyOf(Box::new(obj));
2212 let resolved = keyof.resolve_keyof();
2213 assert!(resolved.is_union());
2214 }
2215
2216 #[test]
2217 fn test_indexed_access() {
2218 let mut props = HashMap::new();
2219 props.insert("name".to_string(), TsValue::String("".to_string()));
2220 let obj = TsValue::Object(props);
2221 let indexed =
2222 TsValue::IndexedAccess { object_type: Box::new(obj), index_type: Box::new(TsValue::String("name".to_string())) };
2223 let resolved = indexed.resolve_indexed_access();
2224 assert!(resolved.is_string());
2225 }
2226}