diff --git a/crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs b/crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs index ffc8d174ca..4c05d6f452 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/assign/mod.rs @@ -6,9 +6,9 @@ use stc_ts_errors::{ DebugExt, ErrorKind, }; use stc_ts_types::{ - Array, Conditional, EnumVariant, Index, Instance, Interface, Intersection, IntrinsicKind, Key, KeywordType, LitType, Mapped, - PropertySignature, QueryExpr, QueryType, Readonly, Ref, StringMapping, ThisType, Tuple, TupleElement, Type, TypeElement, TypeLit, - TypeParam, + Array, Conditional, EnumVariant, Index, IndexedAccessType, Instance, Interface, Intersection, IntrinsicKind, Key, KeywordType, LitType, + Mapped, PropertySignature, QueryExpr, QueryType, Readonly, Ref, StringMapping, ThisType, Tuple, TupleElement, Type, TypeElement, + TypeLit, TypeParam, Union, }; use stc_utils::{cache::Freeze, dev_span, ext::SpanExt, stack}; use swc_atoms::js_word; @@ -521,12 +521,74 @@ impl Analyzer<'_, '_> { } } - match ty { + match ty.normalize() { Type::EnumVariant(e @ EnumVariant { name: Some(..), .. }) => { if opts.ignore_enum_variant_name { return Ok(Cow::Owned(Type::EnumVariant(EnumVariant { name: None, ..e.clone() }))); } } + Type::IndexedAccessType(IndexedAccessType { + obj_type: + obj @ box Type::Param(TypeParam { + span: p_span, + name, + constraint, + .. + }), + index_type: + box Type::Index(Index { + ty: + box Type::Param(TypeParam { + constraint: None, + default: None, + name: rhs_param_name, + .. + }), + .. + }), + .. + }) if name.eq(rhs_param_name) => { + let create_index_accessed_type = |ty: Box, obj| { + Type::IndexedAccessType(IndexedAccessType { + span, + readonly: false, + obj_type: obj, + index_type: ty, + metadata: Default::default(), + tracker: Default::default(), + }) + }; + + let gen_keyword_type = |kind| { + Type::Keyword(KeywordType { + span, + kind, + metadata: Default::default(), + tracker: Default::default(), + }) + }; + + return Ok(Cow::Owned(Type::Union(Union { + span, + types: vec![ + create_index_accessed_type( + Box::new(gen_keyword_type(TsKeywordTypeKind::TsStringKeyword)), + Box::new(*obj.clone()), + ), + create_index_accessed_type( + Box::new(gen_keyword_type(TsKeywordTypeKind::TsNumberKeyword)), + Box::new(*obj.clone()), + ), + create_index_accessed_type( + Box::new(gen_keyword_type(TsKeywordTypeKind::TsSymbolKeyword)), + Box::new(*obj.clone()), + ), + ], + metadata: Default::default(), + tracker: Default::default(), + }))); + } + Type::Conditional(..) | Type::IndexedAccessType(..) | Type::Alias(..) diff --git a/crates/stc_ts_file_analyzer/src/analyzer/expr/mod.rs b/crates/stc_ts_file_analyzer/src/analyzer/expr/mod.rs index a3518d7e92..6b9dd2877a 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/expr/mod.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/expr/mod.rs @@ -25,7 +25,7 @@ use stc_ts_types::{ name::Name, replace::replace_type, ClassMember, ClassProperty, CommonTypeMetadata, ComputedKey, ConstructorSignature, FnParam, Function, Id, Index, Instance, Key, KeywordType, KeywordTypeMetadata, LitType, Method, Module, ModuleTypeData, OptionalType, PropertySignature, QueryExpr, QueryType, QueryTypeMetadata, Readonly, StaticThis, ThisType, TplElem, TplType, TplTypeMetadata, - TypeParamInstantiation, Union, + TypeParamInstantiation, }; use stc_utils::{cache::Freeze, dev_span, ext::TypeVecExt, panic_ctx, stack}; use swc_atoms::js_word; @@ -1835,7 +1835,6 @@ impl Analyzer<'_, '_> { if !self.config.is_builtin { obj.freeze(); } - let mut obj = self.expand( span, obj.into_owned(), @@ -2216,67 +2215,19 @@ impl Analyzer<'_, '_> { } }; - let create_index_accessed_type = |ty: Box, obj| { - Type::IndexedAccessType(IndexedAccessType { - span, - readonly: false, - obj_type: obj, - index_type: ty, - metadata: Default::default(), - tracker: Default::default(), - }) - }; - - if let Type::Index(Index { - ty: - box Type::Param(TypeParam { - constraint: None, - default: None, - name: rhs_param_name, - .. - }), - .. - }) = prop_ty.normalize() - { - if name.eq(rhs_param_name) { - let gen_keyword_type = |kind| { - Type::Keyword(KeywordType { - span, - kind, - metadata: Default::default(), - tracker: Default::default(), - }) - }; - - return Ok(Type::Union(Union { - span, - types: vec![ - create_index_accessed_type( - Box::new(gen_keyword_type(TsKeywordTypeKind::TsStringKeyword)), - Box::new(obj.clone()), - ), - create_index_accessed_type( - Box::new(gen_keyword_type(TsKeywordTypeKind::TsNumberKeyword)), - Box::new(obj.clone()), - ), - create_index_accessed_type( - Box::new(gen_keyword_type(TsKeywordTypeKind::TsSymbolKeyword)), - Box::new(obj.clone()), - ), - ], - metadata: Default::default(), - tracker: Default::default(), - })); - } - } - if is_str_lit_or_union(&prop_ty) { prevent_generalize(&mut prop_ty); } warn!("Creating an indexed access type with type parameter as the object"); - - return Ok(create_index_accessed_type(prop_ty, Box::new(obj))); + return Ok(Type::IndexedAccessType(IndexedAccessType { + span, + readonly: false, + obj_type: Box::new(obj), + index_type: prop_ty, + metadata: Default::default(), + tracker: Default::default(), + })); } Type::Infer(..) => { diff --git a/crates/stc_ts_file_analyzer/tests/pass/controlFlow/guard/typeParams/3.swc-stderr b/crates/stc_ts_file_analyzer/tests/pass/controlFlow/guard/typeParams/3.swc-stderr index 713520bb1e..40e617b51b 100644 --- a/crates/stc_ts_file_analyzer/tests/pass/controlFlow/guard/typeParams/3.swc-stderr +++ b/crates/stc_ts_file_analyzer/tests/pass/controlFlow/guard/typeParams/3.swc-stderr @@ -67,7 +67,7 @@ Error: `---- Error: - > (T[string] | T[number] | T[symbol]) + > T[keyof T] x Type ,-[$DIR/tests/pass/controlFlow/guard/typeParams/3.ts:9:1] diff --git a/crates/stc_ts_file_analyzer/tests/pass/exprs/bin/cmp/typeof/typeParam/3.swc-stderr b/crates/stc_ts_file_analyzer/tests/pass/exprs/bin/cmp/typeof/typeParam/3.swc-stderr index 08e9c86672..75ea4f3fea 100644 --- a/crates/stc_ts_file_analyzer/tests/pass/exprs/bin/cmp/typeof/typeParam/3.swc-stderr +++ b/crates/stc_ts_file_analyzer/tests/pass/exprs/bin/cmp/typeof/typeParam/3.swc-stderr @@ -67,7 +67,7 @@ Error: `---- Error: - > (T[string] | T[number] | T[symbol]) + > T[keyof T] x Type ,-[$DIR/tests/pass/exprs/bin/cmp/typeof/typeParam/3.ts:9:1]