Deduplicate declarations in combined type/value symbols (#23593)

This commit is contained in:
Wesley Wigham 2018-04-21 12:50:05 -07:00 committed by GitHub
parent 7f34340dcf
commit eb112ab492
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 124 additions and 3 deletions

View file

@ -1841,7 +1841,7 @@ namespace ts {
return valueSymbol;
}
const result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName);
result.declarations = concatenate(valueSymbol.declarations, typeSymbol.declarations);
result.declarations = deduplicate(concatenate(valueSymbol.declarations, typeSymbol.declarations), equateValues);
result.parent = valueSymbol.parent || typeSymbol.parent;
if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration;
if (typeSymbol.members) result.members = typeSymbol.members;
@ -1876,7 +1876,7 @@ namespace ts {
let symbolFromVariable: Symbol;
// First check if module was specified with "export=". If so, get the member from the resolved type
if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=" as __String)) {
if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get(InternalSymbolName.ExportEquals)) {
symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText);
}
else {
@ -1889,7 +1889,7 @@ namespace ts {
if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === InternalSymbolName.Default) {
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
}
const symbol = symbolFromModule && symbolFromVariable ?
const symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ?
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
symbolFromModule || symbolFromVariable;
if (!symbol) {

View file

@ -0,0 +1,21 @@
tests/cases/compiler/user.ts(3,5): error TS2322: Type '() => void' is not assignable to type 'string'.
tests/cases/compiler/user.ts(4,5): error TS2322: Type '() => void' is not assignable to type 'string'.
==== tests/cases/compiler/demo.d.ts (0 errors) ====
declare namespace demoNS {
function f(): void;
}
declare module 'demoModule' {
import alias = demoNS;
export = alias;
}
==== tests/cases/compiler/user.ts (2 errors) ====
import { f } from 'demoModule';
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
~~
!!! error TS2322: Type '() => void' is not assignable to type 'string'.
let x2: string = f;
~~
!!! error TS2322: Type '() => void' is not assignable to type 'string'.

View file

@ -0,0 +1,23 @@
//// [tests/cases/compiler/aliasDoesNotDuplicateSignatures.ts] ////
//// [demo.d.ts]
declare namespace demoNS {
function f(): void;
}
declare module 'demoModule' {
import alias = demoNS;
export = alias;
}
//// [user.ts]
import { f } from 'demoModule';
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
let x2: string = f;
//// [user.js]
"use strict";
exports.__esModule = true;
var demoModule_1 = require("demoModule");
// Assign an incorrect type here to see the type of 'f'.
var x1 = demoNS.f;
var x2 = demoModule_1.f;

View file

@ -0,0 +1,32 @@
=== tests/cases/compiler/demo.d.ts ===
declare namespace demoNS {
>demoNS : Symbol(demoNS, Decl(demo.d.ts, 0, 0))
function f(): void;
>f : Symbol(f, Decl(demo.d.ts, 0, 26))
}
declare module 'demoModule' {
>'demoModule' : Symbol('demoModule', Decl(demo.d.ts, 2, 1))
import alias = demoNS;
>alias : Symbol(alias, Decl(demo.d.ts, 3, 29))
>demoNS : Symbol(alias, Decl(demo.d.ts, 0, 0))
export = alias;
>alias : Symbol(alias, Decl(demo.d.ts, 3, 29))
}
=== tests/cases/compiler/user.ts ===
import { f } from 'demoModule';
>f : Symbol(f, Decl(user.ts, 0, 8))
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
>x1 : Symbol(x1, Decl(user.ts, 2, 3))
>demoNS.f : Symbol(f, Decl(demo.d.ts, 0, 26))
>demoNS : Symbol(demoNS, Decl(demo.d.ts, 0, 0))
>f : Symbol(f, Decl(demo.d.ts, 0, 26))
let x2: string = f;
>x2 : Symbol(x2, Decl(user.ts, 3, 3))
>f : Symbol(f, Decl(user.ts, 0, 8))

View file

@ -0,0 +1,32 @@
=== tests/cases/compiler/demo.d.ts ===
declare namespace demoNS {
>demoNS : typeof demoNS
function f(): void;
>f : () => void
}
declare module 'demoModule' {
>'demoModule' : typeof 'demoModule'
import alias = demoNS;
>alias : typeof alias
>demoNS : typeof alias
export = alias;
>alias : typeof alias
}
=== tests/cases/compiler/user.ts ===
import { f } from 'demoModule';
>f : () => void
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
>x1 : string
>demoNS.f : () => void
>demoNS : typeof demoNS
>f : () => void
let x2: string = f;
>x2 : string
>f : () => void

View file

@ -0,0 +1,13 @@
// @filename: demo.d.ts
declare namespace demoNS {
function f(): void;
}
declare module 'demoModule' {
import alias = demoNS;
export = alias;
}
// @filename: user.ts
import { f } from 'demoModule';
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
let x2: string = f;