stc
stc copied to clipboard
Overload handling should handle constructor
Problem
https://github.com/dudykr/stc/blob/269f6c07676f728e667ca5fb4c80d7f17f66a98d/crates/stc_ts_type_checker/tests/conformance/types/objectTypeLiteral/constructSignatures/constructSignaturesWithOverloads2.ts#L15-L24
should pass, but stc fails to verify it.
Currently we only check overloads for methods, so overload selection for new
fails
Solution
We should handle constructor from extract
https://github.com/dudykr/stc/blob/805667830752f229f1674d034e1e9b0eb3fcb076/crates/stc_ts_file_analyzer/src/analyzer/expr/call_new.rs#L1215-L1647
Hi, I would like to take this!
Thanks!
Updated the issue to reflect the real solution
EDIT: GitHub is currently showing this post in the wrong place, this should be after "Updated the issue..." post. Writing this here in case someone is confused...
Ok, so I tried the new real solution by doing something like this:
diff --git a/crates/stc_ts_file_analyzer/src/analyzer/expr/call_new.rs b/crates/stc_ts_file_analyzer/src/analyzer/expr/call_new.rs
index d655cf6e..523e5722 100644
--- a/crates/stc_ts_file_analyzer/src/analyzer/expr/call_new.rs
+++ b/crates/stc_ts_file_analyzer/src/analyzer/expr/call_new.rs
@@ -1515,20 +1515,19 @@ impl Analyzer<'_, '_> {
)
}
- // Type::Constructor(ty::Constructor {
- // ref params,
- // ref type_params,
- // ref ret_ty,
- // ..
- // }) if kind == ExtractKind::New => self.try_instantiate_simple(
- // span,
- // ty.span(),
- // &ret_ty,
- // params,
- // type_params.as_ref(),
- // args,
- // type_args,
- // ),
+ Type::Constructor(c) if kind == ExtractKind::New => self.get_return_type(
+ span,
+ kind,
+ expr,
+ c.type_params.as_ref().map(|v| &*v.params),
+ &c.params,
+ *c.type_ann.clone(),
+ type_args,
+ args,
+ arg_types,
+ spread_arg_types,
+ type_ann,
+ ),
Type::Union(..) => {
self.get_best_return_type(span, expr, ty.clone(), kind, type_args, args, arg_types, spread_arg_types, type_ann)
}
However, I don't see any change in the behaviour. In fact, I don't think it was the path taken by the code anyway. ty
is Type::Union
, so it goes to get_best_return_type()
-> extract_callee_candidates()
, which does add all 3 CallCandidate
s of C2
.
...am I missing something really obvious here?
The type should not be Type::Constructor
. It will be ClassDef
with multiple ClassMember::Consturctor
s.
But in this case, because of the declaration merging of TypeScript, the type will be stored in an intersection or a union (I don't remember exactly)
By stored in
, I mean class C2
and namespace (module C2
) will exist in the same vector, and you may need to adjust logic to exclude namespace (module
keyword, again) from the union or intersection
Oh it's a union. namespace
is rendered as any
in type dump
@kdy1 I think this issue can be closed since it is fixed by #222?
You are right, thanks!