From 43debaaeced72f3c03ee51ff188577c4f622b1a4 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 27 Jul 2023 23:33:14 +0300 Subject: [PATCH 1/2] fix(55168): use setter type for computed prop assignments --- src/compiler/checker.ts | 2 +- .../computedPropertiesWithSetterAssignment.js | 32 +++++++++ ...utedPropertiesWithSetterAssignment.symbols | 61 ++++++++++++++++ ...mputedPropertiesWithSetterAssignment.types | 71 +++++++++++++++++++ .../computedPropertiesWithSetterAssignment.ts | 24 +++++++ 5 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/computedPropertiesWithSetterAssignment.js create mode 100644 tests/baselines/reference/computedPropertiesWithSetterAssignment.symbols create mode 100644 tests/baselines/reference/computedPropertiesWithSetterAssignment.types create mode 100644 tests/cases/compiler/computedPropertiesWithSetterAssignment.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9003ebc18dad7..faaf313159ff9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17379,7 +17379,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return autoType; } } - const propType = getTypeOfSymbol(prop); + const propType = accessFlags & AccessFlags.Writing ? getWriteTypeOfSymbol(prop) : getTypeOfSymbol(prop); return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ? getFlowTypeOfReference(accessExpression, propType) : accessNode && isIndexedAccessTypeNode(accessNode) && containsMissingType(propType) ? getUnionType([propType, undefinedType]) : propType; diff --git a/tests/baselines/reference/computedPropertiesWithSetterAssignment.js b/tests/baselines/reference/computedPropertiesWithSetterAssignment.js new file mode 100644 index 0000000000000..6c61698aa026e --- /dev/null +++ b/tests/baselines/reference/computedPropertiesWithSetterAssignment.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/computedPropertiesWithSetterAssignment.ts] //// + +//// [a.ts] +const k = Symbol(); + +const enum Props { + k = 'k', +} + +interface Foo { + get k(): Set; + set k(v: Iterable); + + get [k](): Set; + set [k](v: Iterable); +} + +declare const foo: Foo; + +foo.k = ['foo']; +foo['k'] = ['foo']; +foo[Props.k] = ['foo']; +foo[k] = ['foo']; + + +//// [a.js] +"use strict"; +const k = Symbol(); +foo.k = ['foo']; +foo['k'] = ['foo']; +foo["k" /* Props.k */] = ['foo']; +foo[k] = ['foo']; diff --git a/tests/baselines/reference/computedPropertiesWithSetterAssignment.symbols b/tests/baselines/reference/computedPropertiesWithSetterAssignment.symbols new file mode 100644 index 0000000000000..a05c5bb8b2aec --- /dev/null +++ b/tests/baselines/reference/computedPropertiesWithSetterAssignment.symbols @@ -0,0 +1,61 @@ +//// [tests/cases/compiler/computedPropertiesWithSetterAssignment.ts] //// + +=== /a.ts === +const k = Symbol(); +>k : Symbol(k, Decl(a.ts, 0, 5)) +>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, --, --)) + +const enum Props { +>Props : Symbol(Props, Decl(a.ts, 0, 19)) + + k = 'k', +>k : Symbol(Props.k, Decl(a.ts, 2, 18)) +} + +interface Foo { +>Foo : Symbol(Foo, Decl(a.ts, 4, 1)) + + get k(): Set; +>k : Symbol(Foo.k, Decl(a.ts, 6, 15), Decl(a.ts, 7, 25)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + set k(v: Iterable); +>k : Symbol(Foo.k, Decl(a.ts, 6, 15), Decl(a.ts, 7, 25)) +>v : Symbol(v, Decl(a.ts, 8, 10)) +>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --)) + + get [k](): Set; +>[k] : Symbol(Foo[k], Decl(a.ts, 8, 31), Decl(a.ts, 10, 27)) +>k : Symbol(k, Decl(a.ts, 0, 5)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + set [k](v: Iterable); +>[k] : Symbol(Foo[k], Decl(a.ts, 8, 31), Decl(a.ts, 10, 27)) +>k : Symbol(k, Decl(a.ts, 0, 5)) +>v : Symbol(v, Decl(a.ts, 11, 12)) +>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --)) +} + +declare const foo: Foo; +>foo : Symbol(foo, Decl(a.ts, 14, 13)) +>Foo : Symbol(Foo, Decl(a.ts, 4, 1)) + +foo.k = ['foo']; +>foo.k : Symbol(Foo.k, Decl(a.ts, 6, 15), Decl(a.ts, 7, 25)) +>foo : Symbol(foo, Decl(a.ts, 14, 13)) +>k : Symbol(Foo.k, Decl(a.ts, 6, 15), Decl(a.ts, 7, 25)) + +foo['k'] = ['foo']; +>foo : Symbol(foo, Decl(a.ts, 14, 13)) +>'k' : Symbol(Foo.k, Decl(a.ts, 6, 15), Decl(a.ts, 7, 25)) + +foo[Props.k] = ['foo']; +>foo : Symbol(foo, Decl(a.ts, 14, 13)) +>Props.k : Symbol(Props.k, Decl(a.ts, 2, 18)) +>Props : Symbol(Props, Decl(a.ts, 0, 19)) +>k : Symbol(Props.k, Decl(a.ts, 2, 18)) + +foo[k] = ['foo']; +>foo : Symbol(foo, Decl(a.ts, 14, 13)) +>k : Symbol(k, Decl(a.ts, 0, 5)) + diff --git a/tests/baselines/reference/computedPropertiesWithSetterAssignment.types b/tests/baselines/reference/computedPropertiesWithSetterAssignment.types new file mode 100644 index 0000000000000..53c50d94c3373 --- /dev/null +++ b/tests/baselines/reference/computedPropertiesWithSetterAssignment.types @@ -0,0 +1,71 @@ +//// [tests/cases/compiler/computedPropertiesWithSetterAssignment.ts] //// + +=== /a.ts === +const k = Symbol(); +>k : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +const enum Props { +>Props : Props + + k = 'k', +>k : Props.k +>'k' : "k" +} + +interface Foo { + get k(): Set; +>k : Set + + set k(v: Iterable); +>k : Set +>v : Iterable + + get [k](): Set; +>[k] : Set +>k : unique symbol + + set [k](v: Iterable); +>[k] : Set +>k : unique symbol +>v : Iterable +} + +declare const foo: Foo; +>foo : Foo + +foo.k = ['foo']; +>foo.k = ['foo'] : string[] +>foo.k : Iterable +>foo : Foo +>k : Iterable +>['foo'] : string[] +>'foo' : "foo" + +foo['k'] = ['foo']; +>foo['k'] = ['foo'] : string[] +>foo['k'] : Iterable +>foo : Foo +>'k' : "k" +>['foo'] : string[] +>'foo' : "foo" + +foo[Props.k] = ['foo']; +>foo[Props.k] = ['foo'] : string[] +>foo[Props.k] : Iterable +>foo : Foo +>Props.k : Props +>Props : typeof Props +>k : Props +>['foo'] : string[] +>'foo' : "foo" + +foo[k] = ['foo']; +>foo[k] = ['foo'] : string[] +>foo[k] : Iterable +>foo : Foo +>k : unique symbol +>['foo'] : string[] +>'foo' : "foo" + diff --git a/tests/cases/compiler/computedPropertiesWithSetterAssignment.ts b/tests/cases/compiler/computedPropertiesWithSetterAssignment.ts new file mode 100644 index 0000000000000..c1fd1623a2bfa --- /dev/null +++ b/tests/cases/compiler/computedPropertiesWithSetterAssignment.ts @@ -0,0 +1,24 @@ +// @target: esnext +// @strict: true +// @filename: /a.ts + +const k = Symbol(); + +const enum Props { + k = 'k', +} + +interface Foo { + get k(): Set; + set k(v: Iterable); + + get [k](): Set; + set [k](v: Iterable); +} + +declare const foo: Foo; + +foo.k = ['foo']; +foo['k'] = ['foo']; +foo[Props.k] = ['foo']; +foo[k] = ['foo']; From 129ff3c28d31b81b324744368fcf460eeb621ad2 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Sun, 6 Oct 2024 18:00:11 +0300 Subject: [PATCH 2/2] update baseline --- ...utedPropertiesWithSetterAssignment.symbols | 4 +- ...mputedPropertiesWithSetterAssignment.types | 41 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/tests/baselines/reference/computedPropertiesWithSetterAssignment.symbols b/tests/baselines/reference/computedPropertiesWithSetterAssignment.symbols index a05c5bb8b2aec..cc82a9dc99a58 100644 --- a/tests/baselines/reference/computedPropertiesWithSetterAssignment.symbols +++ b/tests/baselines/reference/computedPropertiesWithSetterAssignment.symbols @@ -17,7 +17,7 @@ interface Foo { get k(): Set; >k : Symbol(Foo.k, Decl(a.ts, 6, 15), Decl(a.ts, 7, 25)) ->Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) set k(v: Iterable); >k : Symbol(Foo.k, Decl(a.ts, 6, 15), Decl(a.ts, 7, 25)) @@ -27,7 +27,7 @@ interface Foo { get [k](): Set; >[k] : Symbol(Foo[k], Decl(a.ts, 8, 31), Decl(a.ts, 10, 27)) >k : Symbol(k, Decl(a.ts, 0, 5)) ->Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) set [k](v: Iterable); >[k] : Symbol(Foo[k], Decl(a.ts, 8, 31), Decl(a.ts, 10, 27)) diff --git a/tests/baselines/reference/computedPropertiesWithSetterAssignment.types b/tests/baselines/reference/computedPropertiesWithSetterAssignment.types index 53c50d94c3373..92c0df4cfc46d 100644 --- a/tests/baselines/reference/computedPropertiesWithSetterAssignment.types +++ b/tests/baselines/reference/computedPropertiesWithSetterAssignment.types @@ -3,69 +3,110 @@ === /a.ts === const k = Symbol(); >k : unique symbol +> : ^^^^^^^^^^^^^ >Symbol() : unique symbol +> : ^^^^^^^^^^^^^ >Symbol : SymbolConstructor +> : ^^^^^^^^^^^^^^^^^ const enum Props { >Props : Props +> : ^^^^^ k = 'k', >k : Props.k +> : ^^^^^^^ >'k' : "k" +> : ^^^ } interface Foo { get k(): Set; >k : Set +> : ^^^^^^^^^^^ set k(v: Iterable); >k : Set +> : ^^^^^^^^^^^ >v : Iterable +> : ^^^^^^^^^^^^^^^^ get [k](): Set; >[k] : Set +> : ^^^^^^^^^^^ >k : unique symbol +> : ^^^^^^^^^^^^^ set [k](v: Iterable); >[k] : Set +> : ^^^^^^^^^^^ >k : unique symbol +> : ^^^^^^^^^^^^^ >v : Iterable +> : ^^^^^^^^^^^^^^^^ } declare const foo: Foo; >foo : Foo +> : ^^^ foo.k = ['foo']; >foo.k = ['foo'] : string[] +> : ^^^^^^^^ >foo.k : Iterable +> : ^^^^^^^^^^^^^^^^ >foo : Foo +> : ^^^ >k : Iterable +> : ^^^^^^^^^^^^^^^^ >['foo'] : string[] +> : ^^^^^^^^ >'foo' : "foo" +> : ^^^^^ foo['k'] = ['foo']; >foo['k'] = ['foo'] : string[] +> : ^^^^^^^^ >foo['k'] : Iterable +> : ^^^^^^^^^^^^^^^^ >foo : Foo +> : ^^^ >'k' : "k" +> : ^^^ >['foo'] : string[] +> : ^^^^^^^^ >'foo' : "foo" +> : ^^^^^ foo[Props.k] = ['foo']; >foo[Props.k] = ['foo'] : string[] +> : ^^^^^^^^ >foo[Props.k] : Iterable +> : ^^^^^^^^^^^^^^^^ >foo : Foo +> : ^^^ >Props.k : Props +> : ^^^^^ >Props : typeof Props +> : ^^^^^^^^^^^^ >k : Props +> : ^^^^^ >['foo'] : string[] +> : ^^^^^^^^ >'foo' : "foo" +> : ^^^^^ foo[k] = ['foo']; >foo[k] = ['foo'] : string[] +> : ^^^^^^^^ >foo[k] : Iterable +> : ^^^^^^^^^^^^^^^^ >foo : Foo +> : ^^^ >k : unique symbol +> : ^^^^^^^^^^^^^ >['foo'] : string[] +> : ^^^^^^^^ >'foo' : "foo" +> : ^^^^^