@@ -7,8 +7,8 @@ use rustc_hash::FxHasher;
7
7
use crate :: {
8
8
CallArgumentType , DestructureField , Function , FunctionParameter , Literal , MAX_FLATTEN_DEPTH ,
9
9
Resolvable , ResolvedTypeData , ResolvedTypeMember , ResolverId , TypeData , TypeMember ,
10
- TypeReference , TypeResolver , TypeofCallExpression , TypeofExpression ,
11
- TypeofStaticMemberExpression ,
10
+ TypeReference , TypeResolver , TypeofCallExpression , TypeofDestructureExpression ,
11
+ TypeofExpression , TypeofStaticMemberExpression ,
12
12
conditionals:: {
13
13
ConditionalType , reference_to_falsy_subset_of, reference_to_non_nullish_subset_of,
14
14
reference_to_truthy_subset_of,
@@ -119,81 +119,14 @@ pub(super) fn flattened_expression(
119
119
} )
120
120
}
121
121
}
122
- TypeofExpression :: Destructure ( expr) => {
123
- let resolved = resolver. resolve_and_get ( & expr. ty ) ?;
124
- match ( resolved. as_raw_data ( ) , & expr. destructure_field ) {
125
- ( _subject, DestructureField :: Index ( index) ) => Some (
126
- resolved
127
- . to_data ( )
128
- . find_element_type_at_index ( resolved. resolver_id ( ) , resolver, * index)
129
- . map_or_else ( TypeData :: unknown, ResolvedTypeData :: to_data) ,
130
- ) ,
131
- ( _subject, DestructureField :: RestFrom ( index) ) => Some (
132
- resolved
133
- . to_data ( )
134
- . find_type_of_elements_from_index ( resolved. resolver_id ( ) , resolver, * index)
135
- . map_or_else ( TypeData :: unknown, ResolvedTypeData :: to_data) ,
136
- ) ,
137
- ( TypeData :: InstanceOf ( subject_instance) , DestructureField :: Name ( name) ) => resolver
138
- . resolve_and_get ( & resolved. apply_module_id_to_reference ( & subject_instance. ty ) )
139
- . and_then ( |subject| {
140
- subject
141
- . all_members ( resolver)
142
- . find ( |member| !member. is_static ( ) && member. has_name ( name. text ( ) ) )
143
- } )
144
- . and_then ( |member| resolver. resolve_and_get ( & member. deref_ty ( resolver) ) )
145
- . map ( ResolvedTypeData :: to_data) ,
146
- ( TypeData :: InstanceOf ( subject_instance) , DestructureField :: RestExcept ( names) ) => {
147
- resolver
148
- . resolve_and_get (
149
- & resolved. apply_module_id_to_reference ( & subject_instance. ty ) ,
150
- )
151
- . map ( |subject| flattened_rest_object ( resolver, subject, names) )
152
- }
153
- ( subject @ TypeData :: Class ( _) , DestructureField :: Name ( name) ) => {
154
- let member_ty = subject
155
- . own_members ( )
156
- . find ( |own_member| {
157
- own_member. is_static ( ) && own_member. has_name ( name. text ( ) )
158
- } )
159
- . map ( |member| resolved. apply_module_id_to_reference ( & member. ty ) ) ?;
160
- resolver
161
- . resolve_and_get ( & member_ty)
162
- . map ( ResolvedTypeData :: to_data)
163
- }
164
- ( subject @ TypeData :: Class ( _) , DestructureField :: RestExcept ( names) ) => {
165
- let members = subject
166
- . own_members ( )
167
- . filter ( |own_member| {
168
- own_member. is_static ( )
169
- && !names. iter ( ) . any ( |name| own_member. has_name ( name) )
170
- } )
171
- . map ( |member| {
172
- ResolvedTypeMember :: from ( ( resolved. resolver_id ( ) , member) ) . to_member ( )
173
- } )
174
- . collect ( ) ;
175
- Some ( TypeData :: object_with_members ( members) )
176
- }
177
- ( _, DestructureField :: Name ( name) ) => {
178
- let member = resolved
179
- . all_members ( resolver)
180
- . find ( |member| member. has_name ( name. text ( ) ) ) ?;
181
- resolver
182
- . resolve_and_get ( & member. deref_ty ( resolver) )
183
- . map ( ResolvedTypeData :: to_data)
184
- }
185
- ( _, DestructureField :: RestExcept ( excluded_names) ) => {
186
- Some ( flattened_rest_object ( resolver, resolved, excluded_names) )
187
- }
188
- }
189
- }
122
+ TypeofExpression :: Destructure ( expr) => flattened_destructure ( expr, resolver) ,
190
123
TypeofExpression :: Index ( expr) => {
191
124
let object = resolver. resolve_and_get ( & expr. object ) ?;
192
- let element_ty = object
193
- . to_data ( )
194
- . find_element_type_at_index ( object . resolver_id ( ) , resolver, expr . index )
195
- . map_or_else ( TypeData :: unknown , ResolvedTypeData :: to_data ) ;
196
- Some ( element_ty )
125
+ object
126
+ . find_element_type_at_index ( resolver , expr . index )
127
+ . map ( |element_reference| element_reference . into_reference ( resolver) )
128
+ . and_then ( |reference| resolver . resolve_and_get ( & reference ) )
129
+ . map ( ResolvedTypeData :: to_data )
197
130
}
198
131
TypeofExpression :: IterableValueOf ( expr) => {
199
132
let ty = resolver. resolve_and_get ( & expr. ty ) ?;
@@ -325,9 +258,9 @@ pub(super) fn flattened_expression(
325
258
let array = resolver
326
259
. get_by_resolved_id ( GLOBAL_ARRAY_ID )
327
260
. expect ( "Array type must be registered" ) ;
328
- let member = array
329
- . all_members ( resolver )
330
- . find ( |member| member . has_name ( & expr . member ) && !member . is_static ( ) ) ?;
261
+ let member = array. find_member ( resolver , |member| {
262
+ member . has_name ( & expr . member ) && !member . is_static ( )
263
+ } ) ?;
331
264
Some ( TypeData :: reference ( member. ty ( ) . into_owned ( ) ) )
332
265
}
333
266
@@ -356,8 +289,10 @@ pub(super) fn flattened_expression(
356
289
357
290
_ => {
358
291
let member = object
359
- . all_members ( resolver)
360
- . find ( |member| member. has_name ( & expr. member ) ) ?;
292
+ . find_member ( resolver, |member| member. has_name ( & expr. member ) )
293
+ . or_else ( || {
294
+ object. find_index_signature_with_ty ( resolver, |ty| ty. is_string ( ) )
295
+ } ) ?;
361
296
Some ( TypeData :: reference ( member. deref_ty ( resolver) . into_owned ( ) ) )
362
297
}
363
298
}
@@ -411,8 +346,7 @@ fn flattened_call(
411
346
instance_callee. to_data ( )
412
347
} else {
413
348
instance_callee
414
- . all_members ( resolver)
415
- . find ( |member| member. kind ( ) . is_call_signature ( ) )
349
+ . find_member ( resolver, |member| member. kind ( ) . is_call_signature ( ) )
416
350
. map ( ResolvedTypeMember :: to_member)
417
351
. and_then ( |member| resolver. resolve_and_get ( & member. deref_ty ( resolver) ) ) ?
418
352
. to_data ( )
@@ -421,8 +355,7 @@ fn flattened_call(
421
355
TypeData :: Interface ( _) | TypeData :: Object ( _) => {
422
356
callee =
423
357
ResolvedTypeData :: from ( ( ResolverId :: from_level ( resolver. level ( ) ) , & callee) )
424
- . all_members ( resolver)
425
- . find ( |member| member. kind ( ) . is_call_signature ( ) )
358
+ . find_member ( resolver, |member| member. kind ( ) . is_call_signature ( ) )
426
359
. map ( ResolvedTypeMember :: to_member)
427
360
. and_then ( |member| resolver. resolve_and_get ( & member. deref_ty ( resolver) ) ) ?
428
361
. to_data ( ) ;
@@ -434,6 +367,69 @@ fn flattened_call(
434
367
None
435
368
}
436
369
370
+ fn flattened_destructure (
371
+ expr : & TypeofDestructureExpression ,
372
+ resolver : & mut dyn TypeResolver ,
373
+ ) -> Option < TypeData > {
374
+ let resolved = resolver. resolve_and_get ( & expr. ty ) ?;
375
+ match ( resolved. as_raw_data ( ) , & expr. destructure_field ) {
376
+ ( _subject, DestructureField :: Index ( index) ) => resolved
377
+ . find_element_type_at_index ( resolver, * index)
378
+ . map ( |element_reference| element_reference. into_reference ( resolver) )
379
+ . and_then ( |reference| resolver. resolve_and_get ( & reference) )
380
+ . map ( ResolvedTypeData :: to_data) ,
381
+ ( _subject, DestructureField :: RestFrom ( index) ) => {
382
+ resolved. find_type_of_elements_from_index ( resolver, * index)
383
+ }
384
+ ( TypeData :: InstanceOf ( subject_instance) , DestructureField :: Name ( name) ) => resolver
385
+ . resolve_and_get ( & resolved. apply_module_id_to_reference ( & subject_instance. ty ) )
386
+ . and_then ( |subject| {
387
+ subject
388
+ . find_member ( resolver, |member| {
389
+ !member. is_static ( ) && member. has_name ( name. text ( ) )
390
+ } )
391
+ . or_else ( || subject. find_index_signature_with_ty ( resolver, |ty| ty. is_string ( ) ) )
392
+ } )
393
+ . and_then ( |member| resolver. resolve_and_get ( & member. deref_ty ( resolver) ) )
394
+ . map ( ResolvedTypeData :: to_data) ,
395
+ ( TypeData :: InstanceOf ( subject_instance) , DestructureField :: RestExcept ( names) ) => resolver
396
+ . resolve_and_get ( & resolved. apply_module_id_to_reference ( & subject_instance. ty ) )
397
+ . map ( |subject| flattened_rest_object ( resolver, subject, names) ) ,
398
+ ( subject @ TypeData :: Class ( _) , DestructureField :: Name ( name) ) => {
399
+ let member_ty = subject
400
+ . own_members ( )
401
+ . find ( |own_member| own_member. is_static ( ) && own_member. has_name ( name. text ( ) ) )
402
+ . map ( |member| resolved. apply_module_id_to_reference ( & member. ty ) ) ?;
403
+ resolver
404
+ . resolve_and_get ( & member_ty)
405
+ . map ( ResolvedTypeData :: to_data)
406
+ }
407
+ ( subject @ TypeData :: Class ( _) , DestructureField :: RestExcept ( names) ) => {
408
+ let members = subject
409
+ . own_members ( )
410
+ . filter ( |own_member| {
411
+ own_member. is_static ( ) && !names. iter ( ) . any ( |name| own_member. has_name ( name) )
412
+ } )
413
+ . map ( |member| {
414
+ ResolvedTypeMember :: from ( ( resolved. resolver_id ( ) , member) ) . to_member ( )
415
+ } )
416
+ . collect ( ) ;
417
+ Some ( TypeData :: object_with_members ( members) )
418
+ }
419
+ ( _, DestructureField :: Name ( name) ) => {
420
+ let member = resolved
421
+ . find_member ( resolver, |member| member. has_name ( name. text ( ) ) )
422
+ . or_else ( || resolved. find_index_signature_with_ty ( resolver, |ty| ty. is_string ( ) ) ) ?;
423
+ resolver
424
+ . resolve_and_get ( & member. deref_ty ( resolver) )
425
+ . map ( ResolvedTypeData :: to_data)
426
+ }
427
+ ( _, DestructureField :: RestExcept ( excluded_names) ) => {
428
+ Some ( flattened_rest_object ( resolver, resolved, excluded_names) )
429
+ }
430
+ }
431
+ }
432
+
437
433
fn flattened_function_call (
438
434
expr : & TypeofCallExpression ,
439
435
function : & Function ,
0 commit comments