Skip to content

Commit

Permalink
don't duplicate function properties when emiting definitions of overl…
Browse files Browse the repository at this point in the history
…oad signatures (#44235)
  • Loading branch information
Zzzen committed May 24, 2021
1 parent fcabb5c commit 0e1df66
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/compiler/transformers/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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))

Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit 0e1df66

Please sign in to comment.