@@ -8563,7 +8563,9 @@ namespace ts {
8563
8563
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: ReadonlyArray<TypeParameter>): Signature {
8564
8564
const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
8565
8565
if (inferredTypeParameters) {
8566
- const returnSignature = getSingleCallSignature(getReturnTypeOfSignature(instantiatedSignature));
8566
+ const returnType = getReturnTypeOfSignature(instantiatedSignature);
8567
+ const returnSignature = getSingleSignature(returnType, SignatureKind.Call, /*allowMembers*/ false) ||
8568
+ getSingleSignature(returnType, SignatureKind.Construct, /*allowMembers*/ false);
8567
8569
if (returnSignature) {
8568
8570
const newReturnSignature = cloneSignature(returnSignature);
8569
8571
newReturnSignature.typeParameters = inferredTypeParameters;
@@ -8639,7 +8641,8 @@ namespace ts {
8639
8641
// object type literal or interface (using the new keyword). Each way of declaring a constructor
8640
8642
// will result in a different declaration kind.
8641
8643
if (!signature.isolatedSignatureType) {
8642
- const isConstructor = signature.declaration!.kind === SyntaxKind.Constructor || signature.declaration!.kind === SyntaxKind.ConstructSignature; // TODO: GH#18217
8644
+ const kind = signature.declaration ? signature.declaration.kind : SyntaxKind.Unknown;
8645
+ const isConstructor = kind === SyntaxKind.Constructor || kind === SyntaxKind.ConstructSignature || kind === SyntaxKind.ConstructorType;
8643
8646
const type = createObjectType(ObjectFlags.Anonymous);
8644
8647
type.members = emptySymbols;
8645
8648
type.properties = emptyArray;
@@ -20421,11 +20424,19 @@ namespace ts {
20421
20424
20422
20425
// If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
20423
20426
function getSingleCallSignature(type: Type): Signature | undefined {
20427
+ return getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ false);
20428
+ }
20429
+
20430
+ function getSingleSignature(type: Type, kind: SignatureKind, allowMembers: boolean): Signature | undefined {
20424
20431
if (type.flags & TypeFlags.Object) {
20425
20432
const resolved = resolveStructuredTypeMembers(<ObjectType>type);
20426
- if (resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0 &&
20427
- resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
20428
- return resolved.callSignatures[0];
20433
+ if (allowMembers || resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
20434
+ if (kind === SignatureKind.Call && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) {
20435
+ return resolved.callSignatures[0];
20436
+ }
20437
+ if (kind === SignatureKind.Construct && resolved.constructSignatures.length === 1 && resolved.callSignatures.length === 0) {
20438
+ return resolved.constructSignatures[0];
20439
+ }
20429
20440
}
20430
20441
}
20431
20442
return undefined;
@@ -23760,15 +23771,17 @@ namespace ts {
23760
23771
23761
23772
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) {
23762
23773
if (checkMode && checkMode & (CheckMode.Inferential | CheckMode.SkipGenericFunctions)) {
23763
- const signature = getSingleCallSignature(type);
23774
+ const callSignature = getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ true);
23775
+ const constructSignature = getSingleSignature(type, SignatureKind.Construct, /*allowMembers*/ true);
23776
+ const signature = callSignature || constructSignature;
23764
23777
if (signature && signature.typeParameters) {
23765
23778
if (checkMode & CheckMode.SkipGenericFunctions) {
23766
23779
skippedGenericFunction(node, checkMode);
23767
23780
return anyFunctionType;
23768
23781
}
23769
23782
const contextualType = getApparentTypeOfContextualType(<Expression>node);
23770
- if (contextualType) {
23771
- const contextualSignature = getSingleCallSignature (getNonNullableType(contextualType));
23783
+ if (contextualType && !isMixinConstructorType(contextualType) ) {
23784
+ const contextualSignature = getSingleSignature (getNonNullableType(contextualType), callSignature ? SignatureKind.Call : SignatureKind.Construct, /*allowMembers*/ false );
23772
23785
if (contextualSignature && !contextualSignature.typeParameters) {
23773
23786
const context = getInferenceContext(node)!;
23774
23787
// We have an expression that is an argument of a generic function for which we are performing
@@ -23777,7 +23790,10 @@ namespace ts {
23777
23790
// if the outer function returns a function type with a single non-generic call signature and
23778
23791
// if some of the outer function type parameters have no inferences so far. If so, we can
23779
23792
// potentially add inferred type parameters to the outer function return type.
23780
- const returnSignature = context.signature && getSingleCallSignature(getReturnTypeOfSignature(context.signature));
23793
+ const returnType = context.signature && getReturnTypeOfSignature(context.signature);
23794
+ const returnSignature = returnType && (
23795
+ getSingleSignature(returnType, SignatureKind.Call, /*allowMembers*/ false) ||
23796
+ getSingleSignature(returnType, SignatureKind.Construct, /*allowMembers*/ false));
23781
23797
if (returnSignature && !returnSignature.typeParameters && !every(context.inferences, hasInferenceCandidates)) {
23782
23798
// Instantiate the signature with its own type parameters as type arguments, possibly
23783
23799
// renaming the type parameters to ensure they have unique names.
0 commit comments