@@ -8565,7 +8565,7 @@ namespace ts {
85658565 function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: ReadonlyArray<TypeParameter>): Signature {
85668566 const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
85678567 if (inferredTypeParameters) {
8568- const returnSignature = getSingleCallSignature (getReturnTypeOfSignature(instantiatedSignature));
8568+ const returnSignature = getSingleCallOrConstructSignature (getReturnTypeOfSignature(instantiatedSignature));
85698569 if (returnSignature) {
85708570 const newReturnSignature = cloneSignature(returnSignature);
85718571 newReturnSignature.typeParameters = inferredTypeParameters;
@@ -8641,7 +8641,8 @@ namespace ts {
86418641 // object type literal or interface (using the new keyword). Each way of declaring a constructor
86428642 // will result in a different declaration kind.
86438643 if (!signature.isolatedSignatureType) {
8644- 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;
86458646 const type = createObjectType(ObjectFlags.Anonymous);
86468647 type.members = emptySymbols;
86478648 type.properties = emptyArray;
@@ -20630,11 +20631,24 @@ namespace ts {
2063020631
2063120632 // If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
2063220633 function getSingleCallSignature(type: Type): Signature | undefined {
20634+ return getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ false);
20635+ }
20636+
20637+ function getSingleCallOrConstructSignature(type: Type): Signature | undefined {
20638+ return getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ false) ||
20639+ getSingleSignature(type, SignatureKind.Construct, /*allowMembers*/ false);
20640+ }
20641+
20642+ function getSingleSignature(type: Type, kind: SignatureKind, allowMembers: boolean): Signature | undefined {
2063320643 if (type.flags & TypeFlags.Object) {
2063420644 const resolved = resolveStructuredTypeMembers(<ObjectType>type);
20635- if (resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0 &&
20636- resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
20637- return resolved.callSignatures[0];
20645+ if (allowMembers || resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
20646+ if (kind === SignatureKind.Call && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) {
20647+ return resolved.callSignatures[0];
20648+ }
20649+ if (kind === SignatureKind.Construct && resolved.constructSignatures.length === 1 && resolved.callSignatures.length === 0) {
20650+ return resolved.constructSignatures[0];
20651+ }
2063820652 }
2063920653 }
2064020654 return undefined;
@@ -23976,24 +23990,27 @@ namespace ts {
2397623990
2397723991 function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) {
2397823992 if (checkMode && checkMode & (CheckMode.Inferential | CheckMode.SkipGenericFunctions)) {
23979- const signature = getSingleCallSignature(type);
23993+ const callSignature = getSingleSignature(type, SignatureKind.Call, /*allowMembers*/ true);
23994+ const constructSignature = getSingleSignature(type, SignatureKind.Construct, /*allowMembers*/ true);
23995+ const signature = callSignature || constructSignature;
2398023996 if (signature && signature.typeParameters) {
23981- if (checkMode & CheckMode.SkipGenericFunctions) {
23982- skippedGenericFunction(node, checkMode);
23983- return anyFunctionType;
23984- }
2398523997 const contextualType = getApparentTypeOfContextualType(<Expression>node);
23986- if (contextualType) {
23987- const contextualSignature = getSingleCallSignature (getNonNullableType(contextualType));
23998+ if (contextualType && !isMixinConstructorType(contextualType) ) {
23999+ const contextualSignature = getSingleSignature (getNonNullableType(contextualType), callSignature ? SignatureKind.Call : SignatureKind.Construct, /*allowMembers*/ false );
2398824000 if (contextualSignature && !contextualSignature.typeParameters) {
24001+ if (checkMode & CheckMode.SkipGenericFunctions) {
24002+ skippedGenericFunction(node, checkMode);
24003+ return anyFunctionType;
24004+ }
2398924005 const context = getInferenceContext(node)!;
2399024006 // We have an expression that is an argument of a generic function for which we are performing
2399124007 // type argument inference. The expression is of a function type with a single generic call
2399224008 // signature and a contextual function type with a single non-generic call signature. Now check
2399324009 // if the outer function returns a function type with a single non-generic call signature and
2399424010 // if some of the outer function type parameters have no inferences so far. If so, we can
2399524011 // potentially add inferred type parameters to the outer function return type.
23996- const returnSignature = context.signature && getSingleCallSignature(getReturnTypeOfSignature(context.signature));
24012+ const returnType = context.signature && getReturnTypeOfSignature(context.signature);
24013+ const returnSignature = returnType && getSingleCallOrConstructSignature(returnType);
2399724014 if (returnSignature && !returnSignature.typeParameters && !every(context.inferences, hasInferenceCandidates)) {
2399824015 // Instantiate the signature with its own type parameters as type arguments, possibly
2399924016 // renaming the type parameters to ensure they have unique names.
0 commit comments