@@ -8565,7 +8565,7 @@ namespace ts {
8565
8565
function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean, inferredTypeParameters?: ReadonlyArray<TypeParameter>): Signature {
8566
8566
const instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
8567
8567
if (inferredTypeParameters) {
8568
- const returnSignature = getSingleCallSignature (getReturnTypeOfSignature(instantiatedSignature));
8568
+ const returnSignature = getSingleCallOrConstructSignature (getReturnTypeOfSignature(instantiatedSignature));
8569
8569
if (returnSignature) {
8570
8570
const newReturnSignature = cloneSignature(returnSignature);
8571
8571
newReturnSignature.typeParameters = inferredTypeParameters;
@@ -8641,7 +8641,8 @@ namespace ts {
8641
8641
// object type literal or interface (using the new keyword). Each way of declaring a constructor
8642
8642
// will result in a different declaration kind.
8643
8643
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;
8645
8646
const type = createObjectType(ObjectFlags.Anonymous);
8646
8647
type.members = emptySymbols;
8647
8648
type.properties = emptyArray;
@@ -20630,11 +20631,24 @@ namespace ts {
20630
20631
20631
20632
// If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
20632
20633
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 {
20633
20643
if (type.flags & TypeFlags.Object) {
20634
20644
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
+ }
20638
20652
}
20639
20653
}
20640
20654
return undefined;
@@ -23976,24 +23990,27 @@ namespace ts {
23976
23990
23977
23991
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) {
23978
23992
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;
23980
23996
if (signature && signature.typeParameters) {
23981
- if (checkMode & CheckMode.SkipGenericFunctions) {
23982
- skippedGenericFunction(node, checkMode);
23983
- return anyFunctionType;
23984
- }
23985
23997
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 );
23988
24000
if (contextualSignature && !contextualSignature.typeParameters) {
24001
+ if (checkMode & CheckMode.SkipGenericFunctions) {
24002
+ skippedGenericFunction(node, checkMode);
24003
+ return anyFunctionType;
24004
+ }
23989
24005
const context = getInferenceContext(node)!;
23990
24006
// We have an expression that is an argument of a generic function for which we are performing
23991
24007
// type argument inference. The expression is of a function type with a single generic call
23992
24008
// signature and a contextual function type with a single non-generic call signature. Now check
23993
24009
// if the outer function returns a function type with a single non-generic call signature and
23994
24010
// if some of the outer function type parameters have no inferences so far. If so, we can
23995
24011
// 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);
23997
24014
if (returnSignature && !returnSignature.typeParameters && !every(context.inferences, hasInferenceCandidates)) {
23998
24015
// Instantiate the signature with its own type parameters as type arguments, possibly
23999
24016
// renaming the type parameters to ensure they have unique names.
0 commit comments