don't duplicate function properties when emiting definitions of overload signatures (#44235)

This commit is contained in:
Zzzen 2021-05-25 06:52:40 +08:00 committed by GitHub
parent fcabb5c0cc
commit 0e1df66a7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 1 deletions

View file

@ -574,6 +574,16 @@ namespace ts {
return false;
}
// If the ExpandoFunctionDeclaration have multiple overloads, then we only need to emit properties for the last one.
function shouldEmitFunctionProperties(input: FunctionDeclaration) {
if (input.body) {
return true;
}
const overloadSignatures = input.symbol.declarations?.filter(decl => isFunctionDeclaration(decl) && !decl.body);
return !overloadSignatures || overloadSignatures.indexOf(input) === overloadSignatures.length - 1;
}
function getBindingNameVisible(elem: BindingElement | VariableDeclaration | OmittedExpression): boolean {
if (isOmittedExpression(elem)) {
return false;
@ -1194,7 +1204,7 @@ namespace ts {
ensureType(input, input.type),
/*body*/ undefined
));
if (clean && resolver.isExpandoFunctionDeclaration(input)) {
if (clean && resolver.isExpandoFunctionDeclaration(input) && shouldEmitFunctionProperties(input)) {
const props = resolver.getPropertiesOfContainerFunction(input);
// Use parseNodeFactory so it is usable as an enclosing declaration
const fakespace = parseNodeFactory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || factory.createIdentifier("_default"), factory.createModuleBlock([]), NodeFlags.Namespace);

View file

@ -0,0 +1,23 @@
//// [declarationEmitFunctionDuplicateNamespace.ts]
function f(a: 0): 0;
function f(a: 1): 1;
function f(a: 0 | 1) {
return a;
}
f.x = 2;
//// [declarationEmitFunctionDuplicateNamespace.js]
function f(a) {
return a;
}
f.x = 2;
//// [declarationEmitFunctionDuplicateNamespace.d.ts]
declare function f(a: 0): 0;
declare function f(a: 1): 1;
declare namespace f {
var x: number;
}

View file

@ -0,0 +1,22 @@
=== tests/cases/compiler/declarationEmitFunctionDuplicateNamespace.ts ===
function f(a: 0): 0;
>f : Symbol(f, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 0), Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
>a : Symbol(a, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 11))
function f(a: 1): 1;
>f : Symbol(f, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 0), Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
>a : Symbol(a, Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 11))
function f(a: 0 | 1) {
>f : Symbol(f, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 0), Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
>a : Symbol(a, Decl(declarationEmitFunctionDuplicateNamespace.ts, 2, 11))
return a;
>a : Symbol(a, Decl(declarationEmitFunctionDuplicateNamespace.ts, 2, 11))
}
f.x = 2;
>f.x : Symbol(f.x, Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
>f : Symbol(f, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 0), Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
>x : Symbol(f.x, Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))

View file

@ -0,0 +1,24 @@
=== tests/cases/compiler/declarationEmitFunctionDuplicateNamespace.ts ===
function f(a: 0): 0;
>f : typeof f
>a : 0
function f(a: 1): 1;
>f : typeof f
>a : 1
function f(a: 0 | 1) {
>f : typeof f
>a : 0 | 1
return a;
>a : 0 | 1
}
f.x = 2;
>f.x = 2 : 2
>f.x : number
>f : typeof f
>x : number
>2 : 2

View file

@ -0,0 +1,8 @@
// @declaration: true
function f(a: 0): 0;
function f(a: 1): 1;
function f(a: 0 | 1) {
return a;
}
f.x = 2;