Skip to content

Commit

Permalink
feat: Support more keyof for IndexedAccessTypes (#1065)
Browse files Browse the repository at this point in the history
**Description:**

```ts
function f90<T extends S2, K extends keyof S2>(x1: S2[keyof S2], x2: T[keyof S2], x3: S2[K]) {
    x1 = x2;
    x1 = x3;
    x2 = x1;
    x2 = x3;
    x3 = x1;
    x3 = x2;
    x1.length;
    x2.length;
    x3.length;
}
```
  • Loading branch information
sunrabbit123 authored Aug 13, 2023
1 parent e6e4c63 commit 92191dc
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 33 deletions.
5 changes: 3 additions & 2 deletions crates/stc_ts_file_analyzer/src/analyzer/types/keyof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -67,6 +67,7 @@ impl Analyzer<'_, '_> {
}

match ty.normalize() {
Type::Readonly(Readonly { ty, .. }) => return self.keyof(span, ty),
Type::Lit(ty) => {
return self
.keyof(
Expand Down
67 changes: 50 additions & 17 deletions crates/stc_ts_file_analyzer/src/analyzer/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @strict: true


function l<T extends {}, P extends keyof T>(s: string, tp: T[P]): void {
tp = s;
}
function m<T extends { a: number }, P extends keyof T>(s: string, tp: T[P]): void {
tp = s;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"extra_errors": {
"TS2345": 8,
"TS2339": 2,
"TS2322": 12
"TS0": 2,
"TS2322": 8
},
"extra_error_lines": {
"TS2345": [
Expand All @@ -21,11 +22,11 @@
147,
152
],
"TS0": [
286,
338
],
"TS2322": [
307,
309,
310,
311,
326,
327,
328,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Stats {
required_error: 0,
matched_error: 5,
extra_error: 22,
extra_error: 20,
panic: 0,
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"required_errors": {
"TS2322": 1
"TS2322": 2
},
"required_error_lines": {
"TS2322": [
22
25,
28
]
},
"extra_errors": {},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Stats {
required_error: 1,
matched_error: 9,
required_error: 2,
matched_error: 8,
extra_error: 0,
panic: 0,
}
7 changes: 3 additions & 4 deletions crates/stc_ts_type_checker/tests/tsc-stats.rust-debug
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
Stats {
required_error: 3501,
matched_error: 6534,
extra_error: 766,
panic: 73,
required_error: 3502,
matched_error: 6533,
extra_error: 764,
}

0 comments on commit 92191dc

Please sign in to comment.