Skip to content

Commit eb112ab

Browse files
authored
Deduplicate declarations in combined type/value symbols (microsoft#23593)
1 parent 7f34340 commit eb112ab

File tree

6 files changed

+124
-3
lines changed

6 files changed

+124
-3
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,7 +1841,7 @@ namespace ts {
18411841
return valueSymbol;
18421842
}
18431843
const result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName);
1844-
result.declarations = concatenate(valueSymbol.declarations, typeSymbol.declarations);
1844+
result.declarations = deduplicate(concatenate(valueSymbol.declarations, typeSymbol.declarations), equateValues);
18451845
result.parent = valueSymbol.parent || typeSymbol.parent;
18461846
if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration;
18471847
if (typeSymbol.members) result.members = typeSymbol.members;
@@ -1876,7 +1876,7 @@ namespace ts {
18761876

18771877
let symbolFromVariable: Symbol;
18781878
// First check if module was specified with "export=". If so, get the member from the resolved type
1879-
if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=" as __String)) {
1879+
if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get(InternalSymbolName.ExportEquals)) {
18801880
symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText);
18811881
}
18821882
else {
@@ -1889,7 +1889,7 @@ namespace ts {
18891889
if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === InternalSymbolName.Default) {
18901890
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
18911891
}
1892-
const symbol = symbolFromModule && symbolFromVariable ?
1892+
const symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ?
18931893
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
18941894
symbolFromModule || symbolFromVariable;
18951895
if (!symbol) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
tests/cases/compiler/user.ts(3,5): error TS2322: Type '() => void' is not assignable to type 'string'.
2+
tests/cases/compiler/user.ts(4,5): error TS2322: Type '() => void' is not assignable to type 'string'.
3+
4+
5+
==== tests/cases/compiler/demo.d.ts (0 errors) ====
6+
declare namespace demoNS {
7+
function f(): void;
8+
}
9+
declare module 'demoModule' {
10+
import alias = demoNS;
11+
export = alias;
12+
}
13+
==== tests/cases/compiler/user.ts (2 errors) ====
14+
import { f } from 'demoModule';
15+
// Assign an incorrect type here to see the type of 'f'.
16+
let x1: string = demoNS.f;
17+
~~
18+
!!! error TS2322: Type '() => void' is not assignable to type 'string'.
19+
let x2: string = f;
20+
~~
21+
!!! error TS2322: Type '() => void' is not assignable to type 'string'.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [tests/cases/compiler/aliasDoesNotDuplicateSignatures.ts] ////
2+
3+
//// [demo.d.ts]
4+
declare namespace demoNS {
5+
function f(): void;
6+
}
7+
declare module 'demoModule' {
8+
import alias = demoNS;
9+
export = alias;
10+
}
11+
//// [user.ts]
12+
import { f } from 'demoModule';
13+
// Assign an incorrect type here to see the type of 'f'.
14+
let x1: string = demoNS.f;
15+
let x2: string = f;
16+
17+
//// [user.js]
18+
"use strict";
19+
exports.__esModule = true;
20+
var demoModule_1 = require("demoModule");
21+
// Assign an incorrect type here to see the type of 'f'.
22+
var x1 = demoNS.f;
23+
var x2 = demoModule_1.f;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/demo.d.ts ===
2+
declare namespace demoNS {
3+
>demoNS : Symbol(demoNS, Decl(demo.d.ts, 0, 0))
4+
5+
function f(): void;
6+
>f : Symbol(f, Decl(demo.d.ts, 0, 26))
7+
}
8+
declare module 'demoModule' {
9+
>'demoModule' : Symbol('demoModule', Decl(demo.d.ts, 2, 1))
10+
11+
import alias = demoNS;
12+
>alias : Symbol(alias, Decl(demo.d.ts, 3, 29))
13+
>demoNS : Symbol(alias, Decl(demo.d.ts, 0, 0))
14+
15+
export = alias;
16+
>alias : Symbol(alias, Decl(demo.d.ts, 3, 29))
17+
}
18+
=== tests/cases/compiler/user.ts ===
19+
import { f } from 'demoModule';
20+
>f : Symbol(f, Decl(user.ts, 0, 8))
21+
22+
// Assign an incorrect type here to see the type of 'f'.
23+
let x1: string = demoNS.f;
24+
>x1 : Symbol(x1, Decl(user.ts, 2, 3))
25+
>demoNS.f : Symbol(f, Decl(demo.d.ts, 0, 26))
26+
>demoNS : Symbol(demoNS, Decl(demo.d.ts, 0, 0))
27+
>f : Symbol(f, Decl(demo.d.ts, 0, 26))
28+
29+
let x2: string = f;
30+
>x2 : Symbol(x2, Decl(user.ts, 3, 3))
31+
>f : Symbol(f, Decl(user.ts, 0, 8))
32+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
=== tests/cases/compiler/demo.d.ts ===
2+
declare namespace demoNS {
3+
>demoNS : typeof demoNS
4+
5+
function f(): void;
6+
>f : () => void
7+
}
8+
declare module 'demoModule' {
9+
>'demoModule' : typeof 'demoModule'
10+
11+
import alias = demoNS;
12+
>alias : typeof alias
13+
>demoNS : typeof alias
14+
15+
export = alias;
16+
>alias : typeof alias
17+
}
18+
=== tests/cases/compiler/user.ts ===
19+
import { f } from 'demoModule';
20+
>f : () => void
21+
22+
// Assign an incorrect type here to see the type of 'f'.
23+
let x1: string = demoNS.f;
24+
>x1 : string
25+
>demoNS.f : () => void
26+
>demoNS : typeof demoNS
27+
>f : () => void
28+
29+
let x2: string = f;
30+
>x2 : string
31+
>f : () => void
32+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @filename: demo.d.ts
2+
declare namespace demoNS {
3+
function f(): void;
4+
}
5+
declare module 'demoModule' {
6+
import alias = demoNS;
7+
export = alias;
8+
}
9+
// @filename: user.ts
10+
import { f } from 'demoModule';
11+
// Assign an incorrect type here to see the type of 'f'.
12+
let x1: string = demoNS.f;
13+
let x2: string = f;

0 commit comments

Comments
 (0)