@@ -4766,9 +4766,37 @@ namespace ts {
47664766 outer: for (let t of targetSignatures) {
47674767 if (!t.hasStringLiterals || target.flags & TypeFlags.FromSignature) {
47684768 let localErrors = reportErrors;
4769+ let checkedAbstractAssignability = false;
47694770 for (let s of sourceSignatures) {
47704771 if (!s.hasStringLiterals || source.flags & TypeFlags.FromSignature) {
4771- let related = signatureRelatedTo(s, t, localErrors);
4772+ let related = Ternary.True;
4773+
4774+ // Because the "abstractness" of a class is the same across all construct signatures
4775+ // (internally we are checking the corresponding declaration), it is enough to perform
4776+ // the check and report an error once over all pairs of source and target construct signatures.
4777+ if (!checkedAbstractAssignability) {
4778+ checkedAbstractAssignability = true;
4779+
4780+ let sourceErasedSignature = getErasedSignature(s);
4781+ let targetErasedSignature = getErasedSignature(t);
4782+
4783+ let sourceReturnType = sourceErasedSignature && getReturnTypeOfSignature(sourceErasedSignature);
4784+ let targetReturnType = targetErasedSignature && getReturnTypeOfSignature(targetErasedSignature);
4785+
4786+ let sourceReturnDecl = sourceReturnType && sourceReturnType.symbol && getDeclarationOfKind(sourceReturnType.symbol, SyntaxKind.ClassDeclaration);
4787+ let targetReturnDecl = targetReturnType && targetReturnType.symbol && getDeclarationOfKind(targetReturnType.symbol, SyntaxKind.ClassDeclaration);
4788+ let sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & NodeFlags.Abstract;
4789+ let targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & NodeFlags.Abstract;
4790+
4791+ if (sourceIsAbstract && !targetIsAbstract) {
4792+ if (reportErrors) {
4793+ reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
4794+ }
4795+ related = Ternary.False;
4796+ }
4797+ }
4798+
4799+ related &= signatureRelatedTo(s, t, localErrors);
47724800 if (related) {
47734801 result &= related;
47744802 errorInfo = saveErrorInfo;
@@ -4876,18 +4904,6 @@ namespace ts {
48764904 if (targetReturnType === voidType) return result;
48774905 let sourceReturnType = getReturnTypeOfSignature(source);
48784906
4879- let sourceReturnDecl = sourceReturnType.symbol && getDeclarationOfKind(sourceReturnType.symbol, SyntaxKind.ClassDeclaration);
4880- let targetReturnDecl = targetReturnType.symbol && getDeclarationOfKind(targetReturnType.symbol, SyntaxKind.ClassDeclaration);
4881- let sourceIsAbstract = sourceReturnDecl && sourceReturnDecl.flags & NodeFlags.Abstract;
4882- let targetIsAbstract = targetReturnDecl && targetReturnDecl.flags & NodeFlags.Abstract;
4883-
4884- if (sourceIsAbstract && !targetIsAbstract) {
4885- if (reportErrors) {
4886- reportError(Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
4887- }
4888- return Ternary.False;
4889- }
4890-
48914907 return result & isRelatedTo(sourceReturnType, targetReturnType, reportErrors);
48924908 }
48934909
0 commit comments