@@ -26276,8 +26276,9 @@ namespace ts {
2627626276
2627726277 let duplicateFunctionDeclaration = false;
2627826278 let multipleConstructorImplementation = false;
26279+ let hasNonAmbientClass = false;
2627926280 for (const current of declarations) {
26280- const node = <SignatureDeclaration>current;
26281+ const node = <SignatureDeclaration | ClassDeclaration | ClassExpression >current;
2628126282 const inAmbientContext = node.flags & NodeFlags.Ambient;
2628226283 const inAmbientContextOrInterface = node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral || inAmbientContext;
2628326284 if (inAmbientContextOrInterface) {
@@ -26291,6 +26292,10 @@ namespace ts {
2629126292 previousDeclaration = undefined;
2629226293 }
2629326294
26295+ if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && !inAmbientContext) {
26296+ hasNonAmbientClass = true;
26297+ }
26298+
2629426299 if (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature || node.kind === SyntaxKind.Constructor) {
2629526300 const currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
2629626301 someNodeFlags |= currentNodeFlags;
@@ -26339,6 +26344,16 @@ namespace ts {
2633926344 });
2634026345 }
2634126346
26347+ if (hasNonAmbientClass && !isConstructor && symbol.flags & SymbolFlags.Function) {
26348+ // A non-ambient class cannot be an implementation for a non-constructor function/class merge
26349+ // TODO: The below just replicates our older error from when classes and functions were
26350+ // entirely unable to merge - a more helpful message like "Class declaration cannot implement overload list"
26351+ // might be warranted. :shrug:
26352+ forEach(declarations, declaration => {
26353+ addDuplicateDeclarationError(getNameOfDeclaration(declaration) || declaration, Diagnostics.Duplicate_identifier_0, symbolName(symbol), filter(declarations, d => d !== declaration));
26354+ });
26355+ }
26356+
2634226357 // Abstract methods can't have an implementation -- in particular, they don't need one.
2634326358 if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
2634426359 !hasModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) {
@@ -31650,7 +31665,7 @@ namespace ts {
3165031665 if (!symbol || !(symbol.flags & SymbolFlags.Function)) {
3165131666 return false;
3165231667 }
31653- return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && isPropertyAccessExpression(p.valueDeclaration));
31668+ return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && p.valueDeclaration && isPropertyAccessExpression(p.valueDeclaration));
3165431669 }
3165531670
3165631671 function getPropertiesOfContainerFunction(node: Declaration): Symbol[] {
0 commit comments