diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75959107c3f2c..2fac37e39d612 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13645,9 +13645,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { symbol.declarations.push(member); } if (symbolFlags & SymbolFlags.Value) { - if (!symbol.valueDeclaration || symbol.valueDeclaration.kind !== member.kind) { - symbol.valueDeclaration = member; - } + setValueDeclaration(symbol, member); } } diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS1.js b/tests/baselines/reference/lateBoundAssignmentCandidateJS1.js new file mode 100644 index 0000000000000..8770ffab7a640 --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS1.js @@ -0,0 +1,61 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS1.ts] //// + +//// [index.js] +// https://github.com/microsoft/TypeScript/issues/60590 + +export const kBar = Symbol("bar"); + +export class foo0 { + /** + * @protected + * @type {null | string} + */ + [kBar] = null; + + get bar() { + return this[kBar]; + } + /** + * @type {string} + */ + set bar(value) { + this[kBar] = value; + } +} + + +//// [index.js] +// https://github.com/microsoft/TypeScript/issues/60590 +export const kBar = Symbol("bar"); +export class foo0 { + /** + * @protected + * @type {null | string} + */ + [kBar] = null; + get bar() { + return this[kBar]; + } + /** + * @type {string} + */ + set bar(value) { + this[kBar] = value; + } +} + + +//// [index.d.ts] +export const kBar: unique symbol; +export class foo0 { + /** + * @type {string} + */ + set bar(value: string | null); + get bar(): string | null; + /** + * @protected + * @type {null | string} + */ + protected [kBar]: null | string; +} diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS1.symbols b/tests/baselines/reference/lateBoundAssignmentCandidateJS1.symbols new file mode 100644 index 0000000000000..02d82bb513812 --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS1.symbols @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS1.ts] //// + +=== index.js === +// https://github.com/microsoft/TypeScript/issues/60590 + +export const kBar = Symbol("bar"); +>kBar : Symbol(kBar, Decl(index.js, 2, 12)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +export class foo0 { +>foo0 : Symbol(foo0, Decl(index.js, 2, 34)) + + /** + * @protected + * @type {null | string} + */ + [kBar] = null; +>[kBar] : Symbol(foo0[kBar], Decl(index.js, 4, 19)) +>kBar : Symbol(kBar, Decl(index.js, 2, 12)) + + get bar() { +>bar : Symbol(foo0.bar, Decl(index.js, 9, 18), Decl(index.js, 13, 5)) + + return this[kBar]; +>this : Symbol(foo0, Decl(index.js, 2, 34)) +>kBar : Symbol(kBar, Decl(index.js, 2, 12)) + } + /** + * @type {string} + */ + set bar(value) { +>bar : Symbol(foo0.bar, Decl(index.js, 9, 18), Decl(index.js, 13, 5)) +>value : Symbol(value, Decl(index.js, 17, 12)) + + this[kBar] = value; +>this : Symbol(foo0, Decl(index.js, 2, 34)) +>kBar : Symbol(kBar, Decl(index.js, 2, 12)) +>value : Symbol(value, Decl(index.js, 17, 12)) + } +} + diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS1.types b/tests/baselines/reference/lateBoundAssignmentCandidateJS1.types new file mode 100644 index 0000000000000..6f8c1eabcea21 --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS1.types @@ -0,0 +1,64 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS1.ts] //// + +=== index.js === +// https://github.com/microsoft/TypeScript/issues/60590 + +export const kBar = Symbol("bar"); +>kBar : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol("bar") : unique symbol +> : ^^^^^^^^^^^^^ +>Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ +>"bar" : "bar" +> : ^^^^^ + +export class foo0 { +>foo0 : foo0 +> : ^^^^ + + /** + * @protected + * @type {null | string} + */ + [kBar] = null; +>[kBar] : string | null +> : ^^^^^^^^^^^^^ +>kBar : unique symbol +> : ^^^^^^^^^^^^^ + + get bar() { +>bar : string | null +> : ^^^^^^^^^^^^^ + + return this[kBar]; +>this[kBar] : string | null +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ +>kBar : unique symbol +> : ^^^^^^^^^^^^^ + } + /** + * @type {string} + */ + set bar(value) { +>bar : string | null +> : ^^^^^^^^^^^^^ +>value : string | null +> : ^^^^^^^^^^^^^ + + this[kBar] = value; +>this[kBar] = value : string | null +> : ^^^^^^^^^^^^^ +>this[kBar] : string | null +> : ^^^^^^^^^^^^^ +>this : this +> : ^^^^ +>kBar : unique symbol +> : ^^^^^^^^^^^^^ +>value : string | null +> : ^^^^^^^^^^^^^ + } +} + diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS2.js b/tests/baselines/reference/lateBoundAssignmentCandidateJS2.js new file mode 100644 index 0000000000000..64e2b120dd252 --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS2.js @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS2.ts] //// + +//// [index.js] +const prop = 'prop'; + +export class foo1 { + constructor() { + this[prop] = 'bar' + } + + /** + * @protected + * @type {string} + */ + [prop] = 'baz'; +} + + +//// [index.js] +const prop = 'prop'; +export class foo1 { + constructor() { + this[prop] = 'bar'; + } + /** + * @protected + * @type {string} + */ + [prop] = 'baz'; +} + + +//// [index.d.ts] +export class foo1 { + /** + * @protected + * @type {string} + */ + protected prop: string; +} diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS2.symbols b/tests/baselines/reference/lateBoundAssignmentCandidateJS2.symbols new file mode 100644 index 0000000000000..554262a106f56 --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS2.symbols @@ -0,0 +1,24 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS2.ts] //// + +=== index.js === +const prop = 'prop'; +>prop : Symbol(prop, Decl(index.js, 0, 5)) + +export class foo1 { +>foo1 : Symbol(foo1, Decl(index.js, 0, 20)) + + constructor() { + this[prop] = 'bar' +>this : Symbol(foo1, Decl(index.js, 0, 20)) +>prop : Symbol(prop, Decl(index.js, 0, 5)) + } + + /** + * @protected + * @type {string} + */ + [prop] = 'baz'; +>[prop] : Symbol(foo1[prop], Decl(index.js, 5, 5)) +>prop : Symbol(prop, Decl(index.js, 0, 5)) +} + diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS2.types b/tests/baselines/reference/lateBoundAssignmentCandidateJS2.types new file mode 100644 index 0000000000000..1cef472319cba --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS2.types @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS2.ts] //// + +=== index.js === +const prop = 'prop'; +>prop : "prop" +> : ^^^^^^ +>'prop' : "prop" +> : ^^^^^^ + +export class foo1 { +>foo1 : foo1 +> : ^^^^ + + constructor() { + this[prop] = 'bar' +>this[prop] = 'bar' : "bar" +> : ^^^^^ +>this[prop] : string +> : ^^^^^^ +>this : this +> : ^^^^ +>prop : "prop" +> : ^^^^^^ +>'bar' : "bar" +> : ^^^^^ + } + + /** + * @protected + * @type {string} + */ + [prop] = 'baz'; +>[prop] : string +> : ^^^^^^ +>prop : "prop" +> : ^^^^^^ +>'baz' : "baz" +> : ^^^^^ +} + diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS3.errors.txt b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.errors.txt new file mode 100644 index 0000000000000..5e5c1463e2d3c --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.errors.txt @@ -0,0 +1,20 @@ +index.js(5,9): error TS2322: Type 'number' is not assignable to type 'string'. + + +==== index.js (1 errors) ==== + const prop = 'prop'; + + export class foo2 { + constructor() { + this[prop] = 12; + ~~~~~~~~~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + } + + /** + * @protected + * @type {string} + */ + prop = 'baz'; + } + \ No newline at end of file diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS3.js b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.js new file mode 100644 index 0000000000000..ccda0fbb4dd58 --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.js @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS3.ts] //// + +//// [index.js] +const prop = 'prop'; + +export class foo2 { + constructor() { + this[prop] = 12; + } + + /** + * @protected + * @type {string} + */ + prop = 'baz'; +} + + +//// [index.js] +const prop = 'prop'; +export class foo2 { + constructor() { + this[prop] = 12; + } + /** + * @protected + * @type {string} + */ + prop = 'baz'; +} + + +//// [index.d.ts] +export class foo2 { + /** + * @protected + * @type {string} + */ + protected prop: string; +} diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS3.symbols b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.symbols new file mode 100644 index 0000000000000..90d7466bdb7bd --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS3.ts] //// + +=== index.js === +const prop = 'prop'; +>prop : Symbol(prop, Decl(index.js, 0, 5)) + +export class foo2 { +>foo2 : Symbol(foo2, Decl(index.js, 0, 20)) + + constructor() { + this[prop] = 12; +>this : Symbol(foo2, Decl(index.js, 0, 20)) +>prop : Symbol(prop, Decl(index.js, 0, 5)) + } + + /** + * @protected + * @type {string} + */ + prop = 'baz'; +>prop : Symbol(foo2.prop, Decl(index.js, 5, 5), Decl(index.js, 3, 19)) +} + diff --git a/tests/baselines/reference/lateBoundAssignmentCandidateJS3.types b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.types new file mode 100644 index 0000000000000..4ab0adf2ccc4c --- /dev/null +++ b/tests/baselines/reference/lateBoundAssignmentCandidateJS3.types @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/lateBoundAssignmentCandidateJS3.ts] //// + +=== index.js === +const prop = 'prop'; +>prop : "prop" +> : ^^^^^^ +>'prop' : "prop" +> : ^^^^^^ + +export class foo2 { +>foo2 : foo2 +> : ^^^^ + + constructor() { + this[prop] = 12; +>this[prop] = 12 : 12 +> : ^^ +>this[prop] : string +> : ^^^^^^ +>this : this +> : ^^^^ +>prop : "prop" +> : ^^^^^^ +>12 : 12 +> : ^^ + } + + /** + * @protected + * @type {string} + */ + prop = 'baz'; +>prop : string +> : ^^^^^^ +>'baz' : "baz" +> : ^^^^^ +} + diff --git a/tests/baselines/reference/lateBoundMethodNameAssigmentJS.js b/tests/baselines/reference/lateBoundMethodNameAssigmentJS.js index 6dca9a46baa0c..fa537a6cb9b75 100644 --- a/tests/baselines/reference/lateBoundMethodNameAssigmentJS.js +++ b/tests/baselines/reference/lateBoundMethodNameAssigmentJS.js @@ -14,7 +14,7 @@ export class MyClass { //// [lateBoundMethodNameAssigmentJS.d.ts] export class MyClass { - [_symbol]: any; + [_symbol]: () => Promise; } declare const _symbol: unique symbol; export {}; diff --git a/tests/baselines/reference/lateBoundMethodNameAssigmentJS.symbols b/tests/baselines/reference/lateBoundMethodNameAssigmentJS.symbols index 0715b876e7f55..ec3323721f749 100644 --- a/tests/baselines/reference/lateBoundMethodNameAssigmentJS.symbols +++ b/tests/baselines/reference/lateBoundMethodNameAssigmentJS.symbols @@ -12,8 +12,10 @@ export class MyClass { this[_symbol] = this[_symbol].bind(this); >this : Symbol(MyClass, Decl(lateBoundMethodNameAssigmentJS.js, 0, 31)) >_symbol : Symbol(_symbol, Decl(lateBoundMethodNameAssigmentJS.js, 0, 5)) +>this[_symbol].bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >this : Symbol(MyClass, Decl(lateBoundMethodNameAssigmentJS.js, 0, 31)) >_symbol : Symbol(_symbol, Decl(lateBoundMethodNameAssigmentJS.js, 0, 5)) +>bind : Symbol(CallableFunction.bind, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >this : Symbol(MyClass, Decl(lateBoundMethodNameAssigmentJS.js, 0, 31)) } diff --git a/tests/baselines/reference/lateBoundMethodNameAssigmentJS.types b/tests/baselines/reference/lateBoundMethodNameAssigmentJS.types index 5b27e8e4813e9..59fd7fecaccec 100644 --- a/tests/baselines/reference/lateBoundMethodNameAssigmentJS.types +++ b/tests/baselines/reference/lateBoundMethodNameAssigmentJS.types @@ -17,28 +17,33 @@ export class MyClass { constructor() { this[_symbol] = this[_symbol].bind(this); ->this[_symbol] = this[_symbol].bind(this) : error ->this[_symbol] : error +>this[_symbol] = this[_symbol].bind(this) : () => Promise +> : ^^^^^^^^^^^^^^^^^^^ +>this[_symbol] : () => Promise +> : ^^^^^^^^^^^^^^^^^^^ >this : this > : ^^^^ >_symbol : unique symbol > : ^^^^^^^^^^^^^ ->this[_symbol].bind(this) : error ->this[_symbol].bind : error ->this[_symbol] : any -> : ^^^ +>this[_symbol].bind(this) : () => Promise +> : ^^^^^^^^^^^^^^^^^^^ +>this[_symbol].bind : { (this: T, thisArg: ThisParameterType): OmitThisParameter; (this: (this: T, ...args: [...A, ...B]) => R, thisArg: T, ...args: A): (...args: B) => R; } +> : ^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ ^^ ^^^ ^^^ +>this[_symbol] : () => Promise +> : ^^^^^^^^^^^^^^^^^^^ >this : this > : ^^^^ >_symbol : unique symbol > : ^^^^^^^^^^^^^ ->bind : any -> : ^^^ +>bind : { (this: T, thisArg: ThisParameterType): OmitThisParameter; (this: (this: T, ...args: [...A, ...B]) => R, thisArg: T, ...args: A): (...args: B) => R; } +> : ^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ ^^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ ^^ ^^^ ^^^ >this : this > : ^^^^ } async [_symbol]() { } ->[_symbol] : error +>[_symbol] : () => Promise +> : ^^^^^^^^^^^^^^^^^^^ >_symbol : unique symbol > : ^^^^^^^^^^^^^ } diff --git a/tests/cases/compiler/lateBoundAssignmentCandidateJS1.ts b/tests/cases/compiler/lateBoundAssignmentCandidateJS1.ts new file mode 100644 index 0000000000000..be2747421ff75 --- /dev/null +++ b/tests/cases/compiler/lateBoundAssignmentCandidateJS1.ts @@ -0,0 +1,31 @@ +// @strict: true +// @target: esnext +// @lib: esnext +// @declaration: true +// @outDir: dist +// @checkJs: true +// @allowJs: true + +// @filename: index.js + +// https://github.com/microsoft/TypeScript/issues/60590 + +export const kBar = Symbol("bar"); + +export class foo0 { + /** + * @protected + * @type {null | string} + */ + [kBar] = null; + + get bar() { + return this[kBar]; + } + /** + * @type {string} + */ + set bar(value) { + this[kBar] = value; + } +} diff --git a/tests/cases/compiler/lateBoundAssignmentCandidateJS2.ts b/tests/cases/compiler/lateBoundAssignmentCandidateJS2.ts new file mode 100644 index 0000000000000..079dbbc40b983 --- /dev/null +++ b/tests/cases/compiler/lateBoundAssignmentCandidateJS2.ts @@ -0,0 +1,23 @@ +// @strict: true +// @target: esnext +// @lib: esnext +// @declaration: true +// @outDir: dist +// @checkJs: true +// @allowJs: true + +// @filename: index.js + +const prop = 'prop'; + +export class foo1 { + constructor() { + this[prop] = 'bar' + } + + /** + * @protected + * @type {string} + */ + [prop] = 'baz'; +} diff --git a/tests/cases/compiler/lateBoundAssignmentCandidateJS3.ts b/tests/cases/compiler/lateBoundAssignmentCandidateJS3.ts new file mode 100644 index 0000000000000..598cff13fb1f8 --- /dev/null +++ b/tests/cases/compiler/lateBoundAssignmentCandidateJS3.ts @@ -0,0 +1,23 @@ +// @strict: true +// @target: esnext +// @lib: esnext +// @declaration: true +// @outDir: dist +// @checkJs: true +// @allowJs: true + +// @filename: index.js + +const prop = 'prop'; + +export class foo2 { + constructor() { + this[prop] = 12; + } + + /** + * @protected + * @type {string} + */ + prop = 'baz'; +}