diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d6db67d3fa..8568f8cf4a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3166,17 +3166,17 @@ namespace ts { } let type: Type = undefined; - // Handle module.exports = expr or this.p = expr - if (declaration.kind === SyntaxKind.BinaryExpression) { - type = getUnionType(map(symbol.declarations, (decl: BinaryExpression) => checkExpressionCached(decl.right))); - } - else if (declaration.kind === SyntaxKind.PropertyAccessExpression) { - // Declarations only exist for property access expressions for certain - // special assignment kinds - if (declaration.parent.kind === SyntaxKind.BinaryExpression) { - // Handle exports.p = expr or className.prototype.method = expr - type = checkExpressionCached((declaration.parent).right); - } + // Handle certain special assignment kinds, which happen to union across multiple declarations: + // * module.exports = expr + // * exports.p = expr + // * this.p = expr + // * className.prototype.method = expr + if (declaration.kind === SyntaxKind.BinaryExpression || + declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) { + type = getUnionType(map(symbol.declarations, + decl => decl.kind === SyntaxKind.BinaryExpression ? + checkExpressionCached((decl).right) : + checkExpressionCached((decl.parent).right))); } if (type === undefined) { diff --git a/tests/baselines/reference/multipleDeclarations.js b/tests/baselines/reference/multipleDeclarations.js new file mode 100644 index 0000000000..5f5ac29e90 --- /dev/null +++ b/tests/baselines/reference/multipleDeclarations.js @@ -0,0 +1,17 @@ +//// [input.js] + +function C() { + this.m = null; +} +C.prototype.m = function() { + this.nothing(); +}; + + +//// [output.js] +function C() { + this.m = null; +} +C.prototype.m = function () { + this.nothing(); +}; diff --git a/tests/baselines/reference/multipleDeclarations.symbols b/tests/baselines/reference/multipleDeclarations.symbols new file mode 100644 index 0000000000..0c8569ab89 --- /dev/null +++ b/tests/baselines/reference/multipleDeclarations.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/salsa/input.js === + +function C() { +>C : Symbol(C, Decl(input.js, 0, 0)) + + this.m = null; +>m : Symbol(C.m, Decl(input.js, 1, 14), Decl(input.js, 3, 1)) +} +C.prototype.m = function() { +>C.prototype : Symbol(C.m, Decl(input.js, 1, 14), Decl(input.js, 3, 1)) +>C : Symbol(C, Decl(input.js, 0, 0)) +>prototype : Symbol(Function.prototype, Decl(lib.d.ts, --, --)) +>m : Symbol(C.m, Decl(input.js, 1, 14), Decl(input.js, 3, 1)) + + this.nothing(); +}; + diff --git a/tests/baselines/reference/multipleDeclarations.types b/tests/baselines/reference/multipleDeclarations.types new file mode 100644 index 0000000000..7c0a3de70c --- /dev/null +++ b/tests/baselines/reference/multipleDeclarations.types @@ -0,0 +1,29 @@ +=== tests/cases/conformance/salsa/input.js === + +function C() { +>C : () => void + + this.m = null; +>this.m = null : null +>this.m : any +>this : any +>m : any +>null : null +} +C.prototype.m = function() { +>C.prototype.m = function() { this.nothing();} : () => void +>C.prototype.m : any +>C.prototype : any +>C : () => void +>prototype : any +>m : any +>function() { this.nothing();} : () => void + + this.nothing(); +>this.nothing() : any +>this.nothing : any +>this : { m: () => void; } +>nothing : any + +}; + diff --git a/tests/cases/conformance/salsa/multipleDeclarations.ts b/tests/cases/conformance/salsa/multipleDeclarations.ts new file mode 100644 index 0000000000..6899be2ec8 --- /dev/null +++ b/tests/cases/conformance/salsa/multipleDeclarations.ts @@ -0,0 +1,10 @@ +// @filename: input.js +// @out: output.js +// @allowJs: true + +function C() { + this.m = null; +} +C.prototype.m = function() { + this.nothing(); +};