mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Allow functions and ambient classes to merge (#32584)
This commit is contained in:
+17
-2
@@ -26276,8 +26276,9 @@ namespace ts {
|
||||
|
||||
let duplicateFunctionDeclaration = false;
|
||||
let multipleConstructorImplementation = false;
|
||||
let hasNonAmbientClass = false;
|
||||
for (const current of declarations) {
|
||||
const node = <SignatureDeclaration>current;
|
||||
const node = <SignatureDeclaration | ClassDeclaration | ClassExpression>current;
|
||||
const inAmbientContext = node.flags & NodeFlags.Ambient;
|
||||
const inAmbientContextOrInterface = node.parent.kind === SyntaxKind.InterfaceDeclaration || node.parent.kind === SyntaxKind.TypeLiteral || inAmbientContext;
|
||||
if (inAmbientContextOrInterface) {
|
||||
@@ -26291,6 +26292,10 @@ namespace ts {
|
||||
previousDeclaration = undefined;
|
||||
}
|
||||
|
||||
if ((node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression) && !inAmbientContext) {
|
||||
hasNonAmbientClass = true;
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature || node.kind === SyntaxKind.Constructor) {
|
||||
const currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
|
||||
someNodeFlags |= currentNodeFlags;
|
||||
@@ -26339,6 +26344,16 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
if (hasNonAmbientClass && !isConstructor && symbol.flags & SymbolFlags.Function) {
|
||||
// A non-ambient class cannot be an implementation for a non-constructor function/class merge
|
||||
// TODO: The below just replicates our older error from when classes and functions were
|
||||
// entirely unable to merge - a more helpful message like "Class declaration cannot implement overload list"
|
||||
// might be warranted. :shrug:
|
||||
forEach(declarations, declaration => {
|
||||
addDuplicateDeclarationError(getNameOfDeclaration(declaration) || declaration, Diagnostics.Duplicate_identifier_0, symbolName(symbol), filter(declarations, d => d !== declaration));
|
||||
});
|
||||
}
|
||||
|
||||
// Abstract methods can't have an implementation -- in particular, they don't need one.
|
||||
if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
|
||||
!hasModifier(lastSeenNonAmbientDeclaration, ModifierFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) {
|
||||
@@ -31650,7 +31665,7 @@ namespace ts {
|
||||
if (!symbol || !(symbol.flags & SymbolFlags.Function)) {
|
||||
return false;
|
||||
}
|
||||
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && isPropertyAccessExpression(p.valueDeclaration));
|
||||
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && p.valueDeclaration && isPropertyAccessExpression(p.valueDeclaration));
|
||||
}
|
||||
|
||||
function getPropertiesOfContainerFunction(node: Declaration): Symbol[] {
|
||||
|
||||
@@ -3678,8 +3678,8 @@ namespace ts {
|
||||
ParameterExcludes = Value,
|
||||
PropertyExcludes = None,
|
||||
EnumMemberExcludes = Value | Type,
|
||||
FunctionExcludes = Value & ~(Function | ValueModule),
|
||||
ClassExcludes = (Value | Type) & ~(ValueModule | Interface), // class-interface mergability done in checker.ts
|
||||
FunctionExcludes = Value & ~(Function | ValueModule | Class),
|
||||
ClassExcludes = (Value | Type) & ~(ValueModule | Interface | Function), // class-interface mergability done in checker.ts
|
||||
InterfaceExcludes = Type & ~(Interface | Class),
|
||||
RegularEnumExcludes = (Value | Type) & ~(RegularEnum | ValueModule), // regular enums merge only with regular enums and modules
|
||||
ConstEnumExcludes = (Value | Type) & ~ConstEnum, // const enums merge only with const enums
|
||||
|
||||
Reference in New Issue
Block a user