Skip to content

Commit 0e1df66

Browse files
authored
don't duplicate function properties when emiting definitions of overload signatures (microsoft#44235)
1 parent fcabb5c commit 0e1df66

File tree

5 files changed

+88
-1
lines changed

5 files changed

+88
-1
lines changed

src/compiler/transformers/declarations.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,16 @@ namespace ts {
574574
return false;
575575
}
576576

577+
// If the ExpandoFunctionDeclaration have multiple overloads, then we only need to emit properties for the last one.
578+
function shouldEmitFunctionProperties(input: FunctionDeclaration) {
579+
if (input.body) {
580+
return true;
581+
}
582+
583+
const overloadSignatures = input.symbol.declarations?.filter(decl => isFunctionDeclaration(decl) && !decl.body);
584+
return !overloadSignatures || overloadSignatures.indexOf(input) === overloadSignatures.length - 1;
585+
}
586+
577587
function getBindingNameVisible(elem: BindingElement | VariableDeclaration | OmittedExpression): boolean {
578588
if (isOmittedExpression(elem)) {
579589
return false;
@@ -1194,7 +1204,7 @@ namespace ts {
11941204
ensureType(input, input.type),
11951205
/*body*/ undefined
11961206
));
1197-
if (clean && resolver.isExpandoFunctionDeclaration(input)) {
1207+
if (clean && resolver.isExpandoFunctionDeclaration(input) && shouldEmitFunctionProperties(input)) {
11981208
const props = resolver.getPropertiesOfContainerFunction(input);
11991209
// Use parseNodeFactory so it is usable as an enclosing declaration
12001210
const fakespace = parseNodeFactory.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || factory.createIdentifier("_default"), factory.createModuleBlock([]), NodeFlags.Namespace);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [declarationEmitFunctionDuplicateNamespace.ts]
2+
function f(a: 0): 0;
3+
function f(a: 1): 1;
4+
function f(a: 0 | 1) {
5+
return a;
6+
}
7+
8+
f.x = 2;
9+
10+
11+
//// [declarationEmitFunctionDuplicateNamespace.js]
12+
function f(a) {
13+
return a;
14+
}
15+
f.x = 2;
16+
17+
18+
//// [declarationEmitFunctionDuplicateNamespace.d.ts]
19+
declare function f(a: 0): 0;
20+
declare function f(a: 1): 1;
21+
declare namespace f {
22+
var x: number;
23+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/declarationEmitFunctionDuplicateNamespace.ts ===
2+
function f(a: 0): 0;
3+
>f : Symbol(f, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 0), Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
4+
>a : Symbol(a, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 11))
5+
6+
function f(a: 1): 1;
7+
>f : Symbol(f, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 0), Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
8+
>a : Symbol(a, Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 11))
9+
10+
function f(a: 0 | 1) {
11+
>f : Symbol(f, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 0), Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
12+
>a : Symbol(a, Decl(declarationEmitFunctionDuplicateNamespace.ts, 2, 11))
13+
14+
return a;
15+
>a : Symbol(a, Decl(declarationEmitFunctionDuplicateNamespace.ts, 2, 11))
16+
}
17+
18+
f.x = 2;
19+
>f.x : Symbol(f.x, Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
20+
>f : Symbol(f, Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 0), Decl(declarationEmitFunctionDuplicateNamespace.ts, 0, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 1, 20), Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
21+
>x : Symbol(f.x, Decl(declarationEmitFunctionDuplicateNamespace.ts, 4, 1))
22+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/compiler/declarationEmitFunctionDuplicateNamespace.ts ===
2+
function f(a: 0): 0;
3+
>f : typeof f
4+
>a : 0
5+
6+
function f(a: 1): 1;
7+
>f : typeof f
8+
>a : 1
9+
10+
function f(a: 0 | 1) {
11+
>f : typeof f
12+
>a : 0 | 1
13+
14+
return a;
15+
>a : 0 | 1
16+
}
17+
18+
f.x = 2;
19+
>f.x = 2 : 2
20+
>f.x : number
21+
>f : typeof f
22+
>x : number
23+
>2 : 2
24+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// @declaration: true
2+
function f(a: 0): 0;
3+
function f(a: 1): 1;
4+
function f(a: 0 | 1) {
5+
return a;
6+
}
7+
8+
f.x = 2;

0 commit comments

Comments
 (0)