diff --git a/crates/stc_ts_file_analyzer/src/analyzer/types/keyof.rs b/crates/stc_ts_file_analyzer/src/analyzer/types/keyof.rs index c8d610e165..b1892bac52 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/types/keyof.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/types/keyof.rs @@ -5,8 +5,8 @@ use stc_ts_ast_rnode::{RIdent, RNumber, RStr, RTsEntityName, RTsLit}; use stc_ts_errors::{debug::force_dump_type_as_string, DebugExt, ErrorKind}; use stc_ts_type_ops::{is_str_lit_or_union, Fix}; use stc_ts_types::{ - Class, ClassMember, ClassProperty, Index, KeywordType, KeywordTypeMetadata, LitType, Method, MethodSignature, PropertySignature, Ref, - Type, TypeElement, Union, + Class, ClassMember, ClassProperty, Index, KeywordType, KeywordTypeMetadata, LitType, Method, MethodSignature, PropertySignature, + Readonly, Ref, Type, TypeElement, Union, }; use stc_utils::{cache::Freeze, ext::TypeVecExt, stack, try_cache}; use swc_atoms::js_word; @@ -67,6 +67,7 @@ impl Analyzer<'_, '_> { } match ty.normalize() { + Type::Readonly(Readonly { ty, .. }) => return self.keyof(span, ty), Type::Lit(ty) => { return self .keyof( diff --git a/crates/stc_ts_file_analyzer/src/analyzer/types/mod.rs b/crates/stc_ts_file_analyzer/src/analyzer/types/mod.rs index 90dba21dcf..119bbe5f6e 100644 --- a/crates/stc_ts_file_analyzer/src/analyzer/types/mod.rs +++ b/crates/stc_ts_file_analyzer/src/analyzer/types/mod.rs @@ -555,23 +555,56 @@ impl Analyzer<'_, '_> { disallow_unknown_object_property: true, ..self.ctx }; - let prop_ty = self.with_ctx(ctx).access_property( - actual_span, - &obj_ty, - &Key::Computed(ComputedKey { - span: actual_span, - expr: Box::new(RExpr::Invalid(RInvalid { span: actual_span })), - ty: index_ty.clone(), - }), - TypeOfMode::RValue, - IdCtx::Type, - AccessPropertyOpts { - disallow_creating_indexed_type_from_ty_els: true, - disallow_inexact: true, - do_not_use_any_for_object: true, - ..Default::default() - }, - ); + let prop_ty = { + let type_mode = if ctx.in_fn_with_return_type { + TypeOfMode::LValue + } else { + TypeOfMode::RValue + }; + + let mut result = self.with_ctx(ctx).access_property( + actual_span, + &obj_ty, + &Key::Computed(ComputedKey { + span: actual_span, + expr: Box::new(RExpr::Invalid(RInvalid { span: actual_span })), + ty: index_ty.clone(), + }), + type_mode, + IdCtx::Type, + AccessPropertyOpts { + disallow_creating_indexed_type_from_ty_els: true, + disallow_inexact: true, + do_not_use_any_for_object: true, + ..Default::default() + }, + ); + + if result.is_err() { + if let Type::Param(TypeParam { constraint: Some(ty), .. }) = index_ty.normalize() { + let prop = self.normalize(span, Cow::Borrowed(ty), opts)?.into_owned(); + result = self.with_ctx(ctx).access_property( + actual_span, + &obj_ty, + &Key::Computed(ComputedKey { + span: actual_span, + expr: Box::new(RExpr::Invalid(RInvalid { span: actual_span })), + ty: Box::new(prop), + }), + type_mode, + IdCtx::Type, + AccessPropertyOpts { + disallow_creating_indexed_type_from_ty_els: true, + disallow_inexact: true, + do_not_use_any_for_object: true, + ..Default::default() + }, + ); + } + } + + result + }; if let Ok(prop_ty) = prop_ty { if ty.type_eq(&prop_ty) { diff --git a/crates/stc_ts_file_analyzer/tests/tsc/types/nonPrimitive/.1.ts b/crates/stc_ts_file_analyzer/tests/tsc/types/nonPrimitive/.1.ts new file mode 100644 index 0000000000..37063f079b --- /dev/null +++ b/crates/stc_ts_file_analyzer/tests/tsc/types/nonPrimitive/.1.ts @@ -0,0 +1,9 @@ +// @strict: true + + +function l(s: string, tp: T[P]): void { + tp = s; +} +function m(s: string, tp: T[P]): void { + tp = s; +} \ No newline at end of file diff --git a/crates/stc_ts_file_analyzer/tests/tsc/types/nonPrimitive/1.tsc-errors.json b/crates/stc_ts_file_analyzer/tests/tsc/types/nonPrimitive/1.tsc-errors.json new file mode 100644 index 0000000000..13e0e27e98 --- /dev/null +++ b/crates/stc_ts_file_analyzer/tests/tsc/types/nonPrimitive/1.tsc-errors.json @@ -0,0 +1,14 @@ +[ + { + "file": "tests/tsc/types/nonPrimitive/1.ts", + "line": 5, + "col": 5, + "code": 2322 + }, + { + "file": "tests/tsc/types/nonPrimitive/1.ts", + "line": 8, + "col": 5, + "code": 2322 + } +] \ No newline at end of file diff --git a/crates/stc_ts_type_checker/tests/conformance/types/keyof/keyofAndIndexedAccess.error-diff.json b/crates/stc_ts_type_checker/tests/conformance/types/keyof/keyofAndIndexedAccess.error-diff.json index ff6a3adda9..81a6e33df6 100644 --- a/crates/stc_ts_type_checker/tests/conformance/types/keyof/keyofAndIndexedAccess.error-diff.json +++ b/crates/stc_ts_type_checker/tests/conformance/types/keyof/keyofAndIndexedAccess.error-diff.json @@ -4,8 +4,8 @@ "extra_errors": { "TS2345": 8, "TS2339": 2, - "TS2322": 12, - "TS0": 1 + "TS0": 3, + "TS2322": 8 }, "extra_error_lines": { "TS2345": [ @@ -22,11 +22,12 @@ 147, 152 ], + "TS0": [ + 286, + 338, + 523 + ], "TS2322": [ - 307, - 309, - 310, - 311, 326, 327, 328, @@ -35,9 +36,6 @@ 640, 645, 658 - ], - "TS0": [ - 523 ] } } \ No newline at end of file diff --git a/crates/stc_ts_type_checker/tests/conformance/types/keyof/keyofAndIndexedAccess.stats.rust-debug b/crates/stc_ts_type_checker/tests/conformance/types/keyof/keyofAndIndexedAccess.stats.rust-debug index c1d16af4c5..d60ce13a49 100644 --- a/crates/stc_ts_type_checker/tests/conformance/types/keyof/keyofAndIndexedAccess.stats.rust-debug +++ b/crates/stc_ts_type_checker/tests/conformance/types/keyof/keyofAndIndexedAccess.stats.rust-debug @@ -1,6 +1,6 @@ Stats { required_error: 0, matched_error: 5, - extra_error: 23, + extra_error: 21, panic: 0, } \ No newline at end of file diff --git a/crates/stc_ts_type_checker/tests/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.error-diff.json b/crates/stc_ts_type_checker/tests/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.error-diff.json index 3e392f20b1..f8c3529e5f 100644 --- a/crates/stc_ts_type_checker/tests/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.error-diff.json +++ b/crates/stc_ts_type_checker/tests/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.error-diff.json @@ -1,10 +1,11 @@ { "required_errors": { - "TS2322": 1 + "TS2322": 2 }, "required_error_lines": { "TS2322": [ - 22 + 25, + 28 ] }, "extra_errors": {}, diff --git a/crates/stc_ts_type_checker/tests/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.stats.rust-debug b/crates/stc_ts_type_checker/tests/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.stats.rust-debug index 4074730ba8..13ac66ffd7 100644 --- a/crates/stc_ts_type_checker/tests/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.stats.rust-debug +++ b/crates/stc_ts_type_checker/tests/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.stats.rust-debug @@ -1,6 +1,6 @@ Stats { - required_error: 1, - matched_error: 9, + required_error: 2, + matched_error: 8, extra_error: 0, panic: 0, } \ No newline at end of file diff --git a/crates/stc_ts_type_checker/tests/tsc-stats.rust-debug b/crates/stc_ts_type_checker/tests/tsc-stats.rust-debug index 9956d0d163..528a2fcbb4 100644 --- a/crates/stc_ts_type_checker/tests/tsc-stats.rust-debug +++ b/crates/stc_ts_type_checker/tests/tsc-stats.rust-debug @@ -1,6 +1,6 @@ Stats { - required_error: 3502, - matched_error: 6533, - extra_error: 767, + required_error: 3503, + matched_error: 6532, + extra_error: 765, panic: 74, } \ No newline at end of file