From 05fe67ed23f00a0eac2b4423dbcfad4eb11f0569 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 15:20:07 -0700 Subject: [PATCH 01/11] Added more tests. --- .../noImplicitAnyStringIndexerOnObject.ts | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts b/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts index 5e1b943008843..9f2508bfbfbfd 100644 --- a/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts +++ b/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts @@ -14,13 +14,38 @@ var d = { }; const bar = d['hello']; -var e = { - set: (key: string) => 'foobar', - get: (key: string) => 'foobar' -}; -e['hello'] = 'modified'; -e['hello'] += 1; -e['hello'] ++; +{ + let e = { + set: (key: string) => 'foobar', + get: (key: string) => 'foobar' + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello'] ++; +} + +{ + let e = { + set: (key: string) => 'foobar', + get: (key: string, value: string) => 'foobar' + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello'] ++; +} + +{ + let e = { + set: (key: "hello" | "world") => 'foobar', + get: (key: "hello" | "world", value: string) => 'foobar' + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello'] ++; +} const o = { a: 0 }; @@ -42,3 +67,15 @@ o[numEnumKey]; enum StrEnum { a = "a", b = "b" } let strEnumKey: StrEnum; o[strEnumKey]; + + +interface MyMap { + get(key: K): T; + set(key: K, value: T): void; +} + +interface Dog { bark(): void; } +let rover: Dog = { bark() {} }; + +declare let map: MyMap; +map[rover] = "Rover"; From 4a496f9aee92b800b6ae5e037407312e562e0bfa Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 15:41:09 -0700 Subject: [PATCH 02/11] Accepted baselines. --- ...mplicitAnyStringIndexerOnObject.errors.txt | 115 ++++++++++-- .../noImplicitAnyStringIndexerOnObject.js | 90 +++++++-- ...noImplicitAnyStringIndexerOnObject.symbols | 177 ++++++++++++++---- .../noImplicitAnyStringIndexerOnObject.types | 143 +++++++++++++- 4 files changed, 444 insertions(+), 81 deletions(-) diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt index 0d2fc1b860e8e..e3977fbb96d69 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt @@ -4,22 +4,37 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(7,1): error TS7052: E tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(8,13): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(13,13): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; }'. Property 'hello' does not exist on type '{ set: (key: string) => string; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(19,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,1): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(26,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(22,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(23,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(31,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; get: (key: string, value: string) => string; }'. + Property 'hello' does not exist on type '{ set: (key: string) => string; get: (key: string, value: string) => string; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(32,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(34,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. + Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(43,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. + Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(44,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. + Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(45,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. + Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(51,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'. Property 'b' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(30,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(55,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'. Property 'c' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(58,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '{ a: number; }'. Property '[sym]' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(37,1): error TS7053: Element implicitly has an 'any' type because expression of type 'NumEnum' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(62,1): error TS7053: Element implicitly has an 'any' type because expression of type 'NumEnum' can't be used to index type '{ a: number; }'. Property '[NumEnum.a]' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,1): error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(67,1): error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'. Property '[StrEnum.b]' does not exist on type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(79,5): error TS2538: Type 'Dog' cannot be used as an index type. -==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (12 errors) ==== +==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (22 errors) ==== var a = {}["hello"]; ~~~~~~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{}'. @@ -44,19 +59,67 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,1): error TS7053: !!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; }'. !!! error TS7053: Property 'hello' does not exist on type '{ set: (key: string) => string; }'. - var e = { - set: (key: string) => 'foobar', - get: (key: string) => 'foobar' - }; - e['hello'] = 'modified'; - ~~~~~~~~~~ + { + let e = { + set: (key: string) => 'foobar', + get: (key: string) => 'foobar' + }; + e['hello']; + ~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? + e['hello'] = 'modified'; + ~~~~~~~~~~ !!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? - e['hello'] += 1; - ~~~~~~~~~~ + e['hello'] += 1; + ~~~~~~~~~~ !!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? - e['hello'] ++; - ~~~~~~~~~~ + e['hello'] ++; + ~~~~~~~~~~ !!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? + } + + { + let e = { + set: (key: string) => 'foobar', + get: (key: string, value: string) => 'foobar' + }; + e['hello']; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; get: (key: string, value: string) => string; }'. +!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: string) => string; get: (key: string, value: string) => string; }'. + e['hello'] = 'modified'; + ~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? + e['hello'] += 1; + ~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? + e['hello'] ++; + ~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? + } + + { + let e = { + set: (key: "hello" | "world") => 'foobar', + get: (key: "hello" | "world", value: string) => 'foobar' + }; + e['hello']; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. + e['hello'] = 'modified'; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. + e['hello'] += 1; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. + e['hello'] ++; + ~~~~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. + } const o = { a: 0 }; @@ -93,4 +156,18 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,1): error TS7053: ~~~~~~~~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'. !!! error TS7053: Property '[StrEnum.b]' does not exist on type '{ a: number; }'. + + + interface MyMap { + get(key: K): T; + set(key: K, value: T): void; + } + + interface Dog { bark(): void; } + let rover: Dog = { bark() {} }; + + declare let map: MyMap; + map[rover] = "Rover"; + ~~~~~ +!!! error TS2538: Type 'Dog' cannot be used as an index type. \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.js b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.js index 572d9f38caf03..8ea03d2dbcb7c 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.js +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.js @@ -13,13 +13,38 @@ var d = { }; const bar = d['hello']; -var e = { - set: (key: string) => 'foobar', - get: (key: string) => 'foobar' -}; -e['hello'] = 'modified'; -e['hello'] += 1; -e['hello'] ++; +{ + let e = { + set: (key: string) => 'foobar', + get: (key: string) => 'foobar' + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello'] ++; +} + +{ + let e = { + set: (key: string) => 'foobar', + get: (key: string, value: string) => 'foobar' + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello'] ++; +} + +{ + let e = { + set: (key: "hello" | "world") => 'foobar', + get: (key: "hello" | "world", value: string) => 'foobar' + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello'] ++; +} const o = { a: 0 }; @@ -41,6 +66,18 @@ o[numEnumKey]; enum StrEnum { a = "a", b = "b" } let strEnumKey: StrEnum; o[strEnumKey]; + + +interface MyMap { + get(key: K): T; + set(key: K, value: T): void; +} + +interface Dog { bark(): void; } +let rover: Dog = { bark() {} }; + +declare let map: MyMap; +map[rover] = "Rover"; //// [noImplicitAnyStringIndexerOnObject.js] @@ -55,13 +92,36 @@ var d = { set: function (key) { return 'foobar'; } }; var bar = d['hello']; -var e = { - set: function (key) { return 'foobar'; }, - get: function (key) { return 'foobar'; } -}; -e['hello'] = 'modified'; -e['hello'] += 1; -e['hello']++; +{ + var e = { + set: function (key) { return 'foobar'; }, + get: function (key) { return 'foobar'; } + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello']++; +} +{ + var e = { + set: function (key) { return 'foobar'; }, + get: function (key, value) { return 'foobar'; } + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello']++; +} +{ + var e = { + set: function (key) { return 'foobar'; }, + get: function (key, value) { return 'foobar'; } + }; + e['hello']; + e['hello'] = 'modified'; + e['hello'] += 1; + e['hello']++; +} var o = { a: 0 }; o[k]; o[k2]; @@ -80,3 +140,5 @@ var StrEnum; })(StrEnum || (StrEnum = {})); var strEnumKey; o[strEnumKey]; +var rover = { bark: function () { } }; +map[rover] = "Rover"; diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.symbols b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.symbols index 307144b8563ce..d587a573bf945 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.symbols +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.symbols @@ -34,77 +34,174 @@ const bar = d['hello']; >bar : Symbol(bar, Decl(noImplicitAnyStringIndexerOnObject.ts, 12, 5)) >d : Symbol(d, Decl(noImplicitAnyStringIndexerOnObject.ts, 9, 3)) -var e = { ->e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3)) +{ + let e = { +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5)) - set: (key: string) => 'foobar', ->set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 9)) ->key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 8)) + set: (key: string) => 'foobar', +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 11)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 10)) - get: (key: string) => 'foobar' ->get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 33)) ->key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 8)) + get: (key: string) => 'foobar' +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 35)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 17, 10)) -}; -e['hello'] = 'modified'; ->e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3)) + }; + e['hello']; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5)) + + e['hello'] = 'modified'; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5)) + + e['hello'] += 1; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5)) + + e['hello'] ++; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5)) +} + +{ + let e = { +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5)) + + set: (key: string) => 'foobar', +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 11)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 27, 10)) + + get: (key: string, value: string) => 'foobar' +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 27, 35)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 10)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 22)) + + }; + e['hello']; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5)) + + e['hello'] = 'modified'; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5)) + + e['hello'] += 1; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5)) + + e['hello'] ++; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5)) +} + +{ + let e = { +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5)) + + set: (key: "hello" | "world") => 'foobar', +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 11)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 38, 10)) + + get: (key: "hello" | "world", value: string) => 'foobar' +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 38, 46)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 10)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 33)) + + }; + e['hello']; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5)) + + e['hello'] = 'modified'; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5)) -e['hello'] += 1; ->e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3)) + e['hello'] += 1; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5)) -e['hello'] ++; ->e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 14, 3)) + e['hello'] ++; +>e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5)) +} const o = { a: 0 }; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5)) ->a : Symbol(a, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 11)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) +>a : Symbol(a, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 11)) declare const k: "a" | "b" | "c"; ->k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 24, 13)) +>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 13)) o[k]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5)) ->k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 24, 13)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) +>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 13)) declare const k2: "c"; ->k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 13)) +>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 53, 13)) o[k2]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5)) ->k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 13)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) +>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 53, 13)) declare const sym : unique symbol; ->sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 31, 13)) +>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 13)) o[sym]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5)) ->sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 31, 13)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) +>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 13)) enum NumEnum { a, b } ->NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 32, 7)) ->a : Symbol(NumEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 34, 14)) ->b : Symbol(NumEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 34, 17)) +>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 7)) +>a : Symbol(NumEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 59, 14)) +>b : Symbol(NumEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 59, 17)) let numEnumKey: NumEnum; ->numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 35, 3)) ->NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 32, 7)) +>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 60, 3)) +>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 7)) o[numEnumKey]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5)) ->numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 35, 3)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) +>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 60, 3)) enum StrEnum { a = "a", b = "b" } ->StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 36, 14)) ->a : Symbol(StrEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 14)) ->b : Symbol(StrEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 23)) +>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 14)) +>a : Symbol(StrEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 64, 14)) +>b : Symbol(StrEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 64, 23)) let strEnumKey: StrEnum; ->strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 40, 3)) ->StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 36, 14)) +>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 65, 3)) +>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 14)) o[strEnumKey]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 22, 5)) ->strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 40, 3)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) +>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 65, 3)) + + +interface MyMap { +>MyMap : Symbol(MyMap, Decl(noImplicitAnyStringIndexerOnObject.ts, 66, 14)) +>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 16)) +>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 18)) + + get(key: K): T; +>get : Symbol(MyMap.get, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 23)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 70, 6)) +>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 16)) +>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 18)) + + set(key: K, value: T): void; +>set : Symbol(MyMap.set, Decl(noImplicitAnyStringIndexerOnObject.ts, 70, 17)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 71, 6)) +>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 16)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 71, 13)) +>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 18)) +} + +interface Dog { bark(): void; } +>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 72, 1)) +>bark : Symbol(Dog.bark, Decl(noImplicitAnyStringIndexerOnObject.ts, 74, 15)) + +let rover: Dog = { bark() {} }; +>rover : Symbol(rover, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 3)) +>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 72, 1)) +>bark : Symbol(bark, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 18)) + +declare let map: MyMap; +>map : Symbol(map, Decl(noImplicitAnyStringIndexerOnObject.ts, 77, 11)) +>MyMap : Symbol(MyMap, Decl(noImplicitAnyStringIndexerOnObject.ts, 66, 14)) +>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 72, 1)) + +map[rover] = "Rover"; +>map : Symbol(map, Decl(noImplicitAnyStringIndexerOnObject.ts, 77, 11)) +>rover : Symbol(rover, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 3)) diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.types b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.types index fa74a19224806..5935ddcd7f6cc 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.types +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.types @@ -52,42 +52,139 @@ const bar = d['hello']; >d : { set: (key: string) => string; } >'hello' : "hello" -var e = { +{ + let e = { >e : { set: (key: string) => string; get: (key: string) => string; } ->{ set: (key: string) => 'foobar', get: (key: string) => 'foobar'} : { set: (key: string) => string; get: (key: string) => string; } +>{ set: (key: string) => 'foobar', get: (key: string) => 'foobar' } : { set: (key: string) => string; get: (key: string) => string; } - set: (key: string) => 'foobar', + set: (key: string) => 'foobar', >set : (key: string) => string >(key: string) => 'foobar' : (key: string) => string >key : string >'foobar' : "foobar" - get: (key: string) => 'foobar' + get: (key: string) => 'foobar' >get : (key: string) => string >(key: string) => 'foobar' : (key: string) => string >key : string >'foobar' : "foobar" -}; -e['hello'] = 'modified'; + }; + e['hello']; +>e['hello'] : any +>e : { set: (key: string) => string; get: (key: string) => string; } +>'hello' : "hello" + + e['hello'] = 'modified'; >e['hello'] = 'modified' : "modified" >e['hello'] : any >e : { set: (key: string) => string; get: (key: string) => string; } >'hello' : "hello" >'modified' : "modified" -e['hello'] += 1; + e['hello'] += 1; >e['hello'] += 1 : any >e['hello'] : any >e : { set: (key: string) => string; get: (key: string) => string; } >'hello' : "hello" >1 : 1 -e['hello'] ++; + e['hello'] ++; >e['hello'] ++ : number >e['hello'] : any >e : { set: (key: string) => string; get: (key: string) => string; } >'hello' : "hello" +} + +{ + let e = { +>e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>{ set: (key: string) => 'foobar', get: (key: string, value: string) => 'foobar' } : { set: (key: string) => string; get: (key: string, value: string) => string; } + + set: (key: string) => 'foobar', +>set : (key: string) => string +>(key: string) => 'foobar' : (key: string) => string +>key : string +>'foobar' : "foobar" + + get: (key: string, value: string) => 'foobar' +>get : (key: string, value: string) => string +>(key: string, value: string) => 'foobar' : (key: string, value: string) => string +>key : string +>value : string +>'foobar' : "foobar" + + }; + e['hello']; +>e['hello'] : any +>e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>'hello' : "hello" + + e['hello'] = 'modified'; +>e['hello'] = 'modified' : "modified" +>e['hello'] : any +>e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>'hello' : "hello" +>'modified' : "modified" + + e['hello'] += 1; +>e['hello'] += 1 : any +>e['hello'] : any +>e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>'hello' : "hello" +>1 : 1 + + e['hello'] ++; +>e['hello'] ++ : number +>e['hello'] : any +>e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>'hello' : "hello" +} + +{ + let e = { +>e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>{ set: (key: "hello" | "world") => 'foobar', get: (key: "hello" | "world", value: string) => 'foobar' } : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } + + set: (key: "hello" | "world") => 'foobar', +>set : (key: "hello" | "world") => string +>(key: "hello" | "world") => 'foobar' : (key: "hello" | "world") => string +>key : "hello" | "world" +>'foobar' : "foobar" + + get: (key: "hello" | "world", value: string) => 'foobar' +>get : (key: "hello" | "world", value: string) => string +>(key: "hello" | "world", value: string) => 'foobar' : (key: "hello" | "world", value: string) => string +>key : "hello" | "world" +>value : string +>'foobar' : "foobar" + + }; + e['hello']; +>e['hello'] : any +>e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>'hello' : "hello" + + e['hello'] = 'modified'; +>e['hello'] = 'modified' : "modified" +>e['hello'] : any +>e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>'hello' : "hello" +>'modified' : "modified" + + e['hello'] += 1; +>e['hello'] += 1 : any +>e['hello'] : any +>e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>'hello' : "hello" +>1 : 1 + + e['hello'] ++; +>e['hello'] ++ : number +>e['hello'] : any +>e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>'hello' : "hello" +} const o = { a: 0 }; >o : { a: number; } @@ -149,3 +246,33 @@ o[strEnumKey]; >o : { a: number; } >strEnumKey : StrEnum + +interface MyMap { + get(key: K): T; +>get : (key: K) => T +>key : K + + set(key: K, value: T): void; +>set : (key: K, value: T) => void +>key : K +>value : T +} + +interface Dog { bark(): void; } +>bark : () => void + +let rover: Dog = { bark() {} }; +>rover : Dog +>{ bark() {} } : { bark(): void; } +>bark : () => void + +declare let map: MyMap; +>map : MyMap + +map[rover] = "Rover"; +>map[rover] = "Rover" : "Rover" +>map[rover] : any +>map : MyMap +>rover : Dog +>"Rover" : "Rover" + From 4a70cf43b245504f1305ec6035bc3e306b7f39bb Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 15:45:34 -0700 Subject: [PATCH 03/11] Work better with any parameter type. --- src/compiler/checker.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ace3d5ee8cfe2..7c341c9facedc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12015,7 +12015,7 @@ namespace ts { } } else { - const suggestion = getSuggestionForNonexistentIndexSignature(objectType, accessExpression); + const suggestion = getSuggestionForNonexistentIndexSignature(objectType, accessExpression, indexType); if (suggestion !== undefined) { error(accessExpression, Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion); } @@ -23119,15 +23119,13 @@ namespace ts { return suggestion && symbolName(suggestion); } - function getSuggestionForNonexistentIndexSignature(objectType: Type, expr: ElementAccessExpression): string | undefined { + function getSuggestionForNonexistentIndexSignature(objectType: Type, expr: ElementAccessExpression, keyedType: Type): string | undefined { // check if object type has setter or getter - const hasProp = (name: "set" | "get", argCount = 1) => { + function hasProp(name: "set" | "get") { const prop = getPropertyOfObjectType(objectType, <__String>name); if (prop) { const s = getSingleCallSignature(getTypeOfSymbol(prop)); - if (s && getMinArgumentCount(s) === argCount && typeToString(getTypeAtPosition(s, 0)) === "string") { - return true; - } + return !!s && getMinArgumentCount(s) >= 1 && isTypeAssignableTo(keyedType, getTypeAtPosition(s, 0)); } return false; }; From 11c3867860b30d9434951b975b7a754b30b53c4c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 15:45:44 -0700 Subject: [PATCH 04/11] Accepted baselines. --- ...mplicitAnyStringIndexerOnObject.errors.txt | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt index e3977fbb96d69..f1b46fb9eb940 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt @@ -8,19 +8,14 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,3): error TS7052: tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(22,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(23,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(31,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; get: (key: string, value: string) => string; }'. - Property 'hello' does not exist on type '{ set: (key: string) => string; get: (key: string, value: string) => string; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(31,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'get' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(32,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(34,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. - Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(43,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. - Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(44,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. - Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(45,3): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. - Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(43,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(44,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(45,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(51,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'. Property 'b' does not exist on type '{ a: number; }'. tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(55,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'. @@ -85,8 +80,7 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(79,5): error TS2538: }; e['hello']; ~~~~~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; get: (key: string, value: string) => string; }'. -!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: string) => string; get: (key: string, value: string) => string; }'. +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'get' ? e['hello'] = 'modified'; ~~~~~~~~~~ !!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? @@ -105,20 +99,16 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(79,5): error TS2538: }; e['hello']; ~~~~~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. -!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'get' ? e['hello'] = 'modified'; ~~~~~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. -!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? e['hello'] += 1; ~~~~~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. -!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? e['hello'] ++; ~~~~~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. -!!! error TS7053: Property 'hello' does not exist on type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }'. +!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? } const o = { a: 0 }; From 1c429b4f832df4281de3ecfae770314963c0cdcc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 15:47:29 -0700 Subject: [PATCH 05/11] Use the actual indexed expression. --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7c341c9facedc..490c228831278 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23135,7 +23135,7 @@ namespace ts { return undefined; } - let suggestion = tryGetPropertyAccessOrIdentifierToString(expr); + let suggestion = tryGetPropertyAccessOrIdentifierToString(expr.expression); if (suggestion === undefined) { suggestion = suggestedMethod; } From d2b213990d91a75a45e57cedd50c5587d0e4f7ec Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 15:56:14 -0700 Subject: [PATCH 06/11] Add tests that exhibit bad stringification. --- .../noImplicitAnyStringIndexerOnObject.ts | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts b/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts index 9f2508bfbfbfd..a9b11e29034f4 100644 --- a/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts +++ b/tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts @@ -16,8 +16,8 @@ const bar = d['hello']; { let e = { - set: (key: string) => 'foobar', - get: (key: string) => 'foobar' + get: (key: string) => 'foobar', + set: (key: string) => 'foobar' }; e['hello']; e['hello'] = 'modified'; @@ -27,8 +27,8 @@ const bar = d['hello']; { let e = { - set: (key: string) => 'foobar', - get: (key: string, value: string) => 'foobar' + get: (key: string) => 'foobar', + set: (key: string, value: string) => 'foobar' }; e['hello']; e['hello'] = 'modified'; @@ -38,8 +38,8 @@ const bar = d['hello']; { let e = { - set: (key: "hello" | "world") => 'foobar', - get: (key: "hello" | "world", value: string) => 'foobar' + get: (key: "hello" | "world") => 'foobar', + set: (key: "hello" | "world", value: string) => 'foobar' }; e['hello']; e['hello'] = 'modified'; @@ -47,6 +47,20 @@ const bar = d['hello']; e['hello'] ++; } +{ + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello']; + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified'; + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1; + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++; +} + +{ + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello']; + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified'; + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1; + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++; +} + const o = { a: 0 }; declare const k: "a" | "b" | "c"; From b7e3ab6fe1a99dd22047c3fadf8f1e8b48980230 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 15:56:30 -0700 Subject: [PATCH 07/11] Accepted baselines. --- ...mplicitAnyStringIndexerOnObject.errors.txt | 120 +++++++---- .../noImplicitAnyStringIndexerOnObject.js | 50 +++-- ...noImplicitAnyStringIndexerOnObject.symbols | 190 +++++++++++----- .../noImplicitAnyStringIndexerOnObject.types | 202 +++++++++++++++--- 4 files changed, 420 insertions(+), 142 deletions(-) diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt index f1b46fb9eb940..cceaee0745a81 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt @@ -1,35 +1,43 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(1,9): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{}'. Property 'hello' does not exist on type '{}'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(7,1): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(8,13): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(7,1): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(8,13): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(13,13): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; }'. Property 'hello' does not exist on type '{ set: (key: string) => string; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(22,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(23,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(31,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(32,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(34,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(43,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(44,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(45,3): error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(51,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(22,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(23,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(31,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(32,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(34,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(43,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(44,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(45,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(49,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(50,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(51,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(52,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(56,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(57,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(58,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(59,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(65,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'. Property 'b' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(55,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(69,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'. Property 'c' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(58,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(72,1): error TS7053: Element implicitly has an 'any' type because expression of type 'unique symbol' can't be used to index type '{ a: number; }'. Property '[sym]' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(62,1): error TS7053: Element implicitly has an 'any' type because expression of type 'NumEnum' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(76,1): error TS7053: Element implicitly has an 'any' type because expression of type 'NumEnum' can't be used to index type '{ a: number; }'. Property '[NumEnum.a]' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(67,1): error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(81,1): error TS7053: Element implicitly has an 'any' type because expression of type 'StrEnum' can't be used to index type '{ a: number; }'. Property '[StrEnum.b]' does not exist on type '{ a: number; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(79,5): error TS2538: Type 'Dog' cannot be used as an index type. +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538: Type 'Dog' cannot be used as an index type. -==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (22 errors) ==== +==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (30 errors) ==== var a = {}["hello"]; ~~~~~~~~~~~ !!! error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{}'. @@ -41,10 +49,10 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(79,5): error TS2538: }; c['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get' ? const foo = c['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get' ? var d = { set: (key: string) => 'foobar' @@ -56,59 +64,89 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(79,5): error TS2538: { let e = { - set: (key: string) => 'foobar', - get: (key: string) => 'foobar' + get: (key: string) => 'foobar', + set: (key: string) => 'foobar' }; e['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.get' ? e['hello'] = 'modified'; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? e['hello'] += 1; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? e['hello'] ++; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? } { let e = { - set: (key: string) => 'foobar', - get: (key: string, value: string) => 'foobar' + get: (key: string) => 'foobar', + set: (key: string, value: string) => 'foobar' }; e['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.get' ? e['hello'] = 'modified'; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? e['hello'] += 1; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? e['hello'] ++; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: string) => string; get: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? } { let e = { - set: (key: "hello" | "world") => 'foobar', - get: (key: "hello" | "world", value: string) => 'foobar' + get: (key: "hello" | "world") => 'foobar', + set: (key: "hello" | "world", value: string) => 'foobar' }; e['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.get' ? e['hello'] = 'modified'; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? e['hello'] += 1; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? e['hello'] ++; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? + } + + { + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello']; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get' ? + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified'; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? + } + + { + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello']; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].get' ? + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified'; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? } const o = { a: 0 }; diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.js b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.js index 8ea03d2dbcb7c..aade38856d0c3 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.js +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.js @@ -15,8 +15,8 @@ const bar = d['hello']; { let e = { - set: (key: string) => 'foobar', - get: (key: string) => 'foobar' + get: (key: string) => 'foobar', + set: (key: string) => 'foobar' }; e['hello']; e['hello'] = 'modified'; @@ -26,8 +26,8 @@ const bar = d['hello']; { let e = { - set: (key: string) => 'foobar', - get: (key: string, value: string) => 'foobar' + get: (key: string) => 'foobar', + set: (key: string, value: string) => 'foobar' }; e['hello']; e['hello'] = 'modified'; @@ -37,8 +37,8 @@ const bar = d['hello']; { let e = { - set: (key: "hello" | "world") => 'foobar', - get: (key: "hello" | "world", value: string) => 'foobar' + get: (key: "hello" | "world") => 'foobar', + set: (key: "hello" | "world", value: string) => 'foobar' }; e['hello']; e['hello'] = 'modified'; @@ -46,6 +46,20 @@ const bar = d['hello']; e['hello'] ++; } +{ + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello']; + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified'; + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1; + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++; +} + +{ + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello']; + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified'; + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1; + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++; +} + const o = { a: 0 }; declare const k: "a" | "b" | "c"; @@ -94,8 +108,8 @@ var d = { var bar = d['hello']; { var e = { - set: function (key) { return 'foobar'; }, - get: function (key) { return 'foobar'; } + get: function (key) { return 'foobar'; }, + set: function (key) { return 'foobar'; } }; e['hello']; e['hello'] = 'modified'; @@ -104,8 +118,8 @@ var bar = d['hello']; } { var e = { - set: function (key) { return 'foobar'; }, - get: function (key, value) { return 'foobar'; } + get: function (key) { return 'foobar'; }, + set: function (key, value) { return 'foobar'; } }; e['hello']; e['hello'] = 'modified'; @@ -114,14 +128,26 @@ var bar = d['hello']; } { var e = { - set: function (key) { return 'foobar'; }, - get: function (key, value) { return 'foobar'; } + get: function (key) { return 'foobar'; }, + set: function (key, value) { return 'foobar'; } }; e['hello']; e['hello'] = 'modified'; e['hello'] += 1; e['hello']++; } +{ + ({ get: function (key) { return 'hello'; }, set: function (key, value) { } })['hello']; + ({ get: function (key) { return 'hello'; }, set: function (key, value) { } })['hello'] = 'modified'; + ({ get: function (key) { return 'hello'; }, set: function (key, value) { } })['hello'] += 1; + ({ get: function (key) { return 'hello'; }, set: function (key, value) { } })['hello']++; +} +{ + ({ foo: { get: function (key) { return 'hello'; }, set: function (key, value) { } } }).foo['hello']; + ({ foo: { get: function (key) { return 'hello'; }, set: function (key, value) { } } }).foo['hello'] = 'modified'; + ({ foo: { get: function (key) { return 'hello'; }, set: function (key, value) { } } }).foo['hello'] += 1; + ({ foo: { get: function (key) { return 'hello'; }, set: function (key, value) { } } }).foo['hello']++; +} var o = { a: 0 }; o[k]; o[k2]; diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.symbols b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.symbols index d587a573bf945..173616239655b 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.symbols +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.symbols @@ -38,12 +38,12 @@ const bar = d['hello']; let e = { >e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 5)) - set: (key: string) => 'foobar', ->set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 11)) + get: (key: string) => 'foobar', +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 15, 11)) >key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 10)) - get: (key: string) => 'foobar' ->get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 35)) + set: (key: string) => 'foobar' +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 16, 35)) >key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 17, 10)) }; @@ -64,12 +64,12 @@ const bar = d['hello']; let e = { >e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 5)) - set: (key: string) => 'foobar', ->set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 11)) + get: (key: string) => 'foobar', +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 26, 11)) >key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 27, 10)) - get: (key: string, value: string) => 'foobar' ->get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 27, 35)) + set: (key: string, value: string) => 'foobar' +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 27, 35)) >key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 10)) >value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 28, 22)) @@ -91,12 +91,12 @@ const bar = d['hello']; let e = { >e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5)) - set: (key: "hello" | "world") => 'foobar', ->set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 11)) + get: (key: "hello" | "world") => 'foobar', +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 11)) >key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 38, 10)) - get: (key: "hello" | "world", value: string) => 'foobar' ->get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 38, 46)) + set: (key: "hello" | "world", value: string) => 'foobar' +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 38, 46)) >key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 10)) >value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 39, 33)) @@ -114,94 +114,166 @@ const bar = d['hello']; >e : Symbol(e, Decl(noImplicitAnyStringIndexerOnObject.ts, 37, 5)) } +{ + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello']; +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 4)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 11)) +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 35)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 42)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 48, 54)) + + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified'; +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 4)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 11)) +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 35)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 42)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 54)) + + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1; +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 4)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 11)) +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 35)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 42)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 50, 54)) + + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++; +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 4)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 11)) +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 35)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 42)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 51, 54)) +} + +{ + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello']; +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 4)) +>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 4)) +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 11)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 18)) +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 42)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 49)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 61)) +>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 55, 4)) + + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified'; +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 4)) +>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 4)) +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 11)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 18)) +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 42)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 49)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 61)) +>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 4)) + + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1; +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 4)) +>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 4)) +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 11)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 18)) +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 42)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 49)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 61)) +>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 4)) + + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++; +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 4)) +>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 4)) +>get : Symbol(get, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 11)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 18)) +>set : Symbol(set, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 42)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 49)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 61)) +>foo : Symbol(foo, Decl(noImplicitAnyStringIndexerOnObject.ts, 58, 4)) +} + const o = { a: 0 }; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) ->a : Symbol(a, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 11)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5)) +>a : Symbol(a, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 11)) declare const k: "a" | "b" | "c"; ->k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 13)) +>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 63, 13)) o[k]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) ->k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 49, 13)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5)) +>k : Symbol(k, Decl(noImplicitAnyStringIndexerOnObject.ts, 63, 13)) declare const k2: "c"; ->k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 53, 13)) +>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 67, 13)) o[k2]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) ->k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 53, 13)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5)) +>k2 : Symbol(k2, Decl(noImplicitAnyStringIndexerOnObject.ts, 67, 13)) declare const sym : unique symbol; ->sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 13)) +>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 70, 13)) o[sym]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) ->sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 56, 13)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5)) +>sym : Symbol(sym, Decl(noImplicitAnyStringIndexerOnObject.ts, 70, 13)) enum NumEnum { a, b } ->NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 7)) ->a : Symbol(NumEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 59, 14)) ->b : Symbol(NumEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 59, 17)) +>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 71, 7)) +>a : Symbol(NumEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 73, 14)) +>b : Symbol(NumEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 73, 17)) let numEnumKey: NumEnum; ->numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 60, 3)) ->NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 57, 7)) +>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 74, 3)) +>NumEnum : Symbol(NumEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 71, 7)) o[numEnumKey]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) ->numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 60, 3)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5)) +>numEnumKey : Symbol(numEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 74, 3)) enum StrEnum { a = "a", b = "b" } ->StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 14)) ->a : Symbol(StrEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 64, 14)) ->b : Symbol(StrEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 64, 23)) +>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 14)) +>a : Symbol(StrEnum.a, Decl(noImplicitAnyStringIndexerOnObject.ts, 78, 14)) +>b : Symbol(StrEnum.b, Decl(noImplicitAnyStringIndexerOnObject.ts, 78, 23)) let strEnumKey: StrEnum; ->strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 65, 3)) ->StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 14)) +>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 79, 3)) +>StrEnum : Symbol(StrEnum, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 14)) o[strEnumKey]; ->o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 47, 5)) ->strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 65, 3)) +>o : Symbol(o, Decl(noImplicitAnyStringIndexerOnObject.ts, 61, 5)) +>strEnumKey : Symbol(strEnumKey, Decl(noImplicitAnyStringIndexerOnObject.ts, 79, 3)) interface MyMap { ->MyMap : Symbol(MyMap, Decl(noImplicitAnyStringIndexerOnObject.ts, 66, 14)) ->K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 16)) ->T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 18)) +>MyMap : Symbol(MyMap, Decl(noImplicitAnyStringIndexerOnObject.ts, 80, 14)) +>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 16)) +>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 18)) get(key: K): T; ->get : Symbol(MyMap.get, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 23)) ->key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 70, 6)) ->K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 16)) ->T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 18)) +>get : Symbol(MyMap.get, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 23)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 84, 6)) +>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 16)) +>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 18)) set(key: K, value: T): void; ->set : Symbol(MyMap.set, Decl(noImplicitAnyStringIndexerOnObject.ts, 70, 17)) ->key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 71, 6)) ->K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 16)) ->value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 71, 13)) ->T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 69, 18)) +>set : Symbol(MyMap.set, Decl(noImplicitAnyStringIndexerOnObject.ts, 84, 17)) +>key : Symbol(key, Decl(noImplicitAnyStringIndexerOnObject.ts, 85, 6)) +>K : Symbol(K, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 16)) +>value : Symbol(value, Decl(noImplicitAnyStringIndexerOnObject.ts, 85, 13)) +>T : Symbol(T, Decl(noImplicitAnyStringIndexerOnObject.ts, 83, 18)) } interface Dog { bark(): void; } ->Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 72, 1)) ->bark : Symbol(Dog.bark, Decl(noImplicitAnyStringIndexerOnObject.ts, 74, 15)) +>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 86, 1)) +>bark : Symbol(Dog.bark, Decl(noImplicitAnyStringIndexerOnObject.ts, 88, 15)) let rover: Dog = { bark() {} }; ->rover : Symbol(rover, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 3)) ->Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 72, 1)) ->bark : Symbol(bark, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 18)) +>rover : Symbol(rover, Decl(noImplicitAnyStringIndexerOnObject.ts, 89, 3)) +>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 86, 1)) +>bark : Symbol(bark, Decl(noImplicitAnyStringIndexerOnObject.ts, 89, 18)) declare let map: MyMap; ->map : Symbol(map, Decl(noImplicitAnyStringIndexerOnObject.ts, 77, 11)) ->MyMap : Symbol(MyMap, Decl(noImplicitAnyStringIndexerOnObject.ts, 66, 14)) ->Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 72, 1)) +>map : Symbol(map, Decl(noImplicitAnyStringIndexerOnObject.ts, 91, 11)) +>MyMap : Symbol(MyMap, Decl(noImplicitAnyStringIndexerOnObject.ts, 80, 14)) +>Dog : Symbol(Dog, Decl(noImplicitAnyStringIndexerOnObject.ts, 86, 1)) map[rover] = "Rover"; ->map : Symbol(map, Decl(noImplicitAnyStringIndexerOnObject.ts, 77, 11)) ->rover : Symbol(rover, Decl(noImplicitAnyStringIndexerOnObject.ts, 75, 3)) +>map : Symbol(map, Decl(noImplicitAnyStringIndexerOnObject.ts, 91, 11)) +>rover : Symbol(rover, Decl(noImplicitAnyStringIndexerOnObject.ts, 89, 3)) diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.types b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.types index 5935ddcd7f6cc..4a12805418b68 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.types +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.types @@ -54,17 +54,17 @@ const bar = d['hello']; { let e = { ->e : { set: (key: string) => string; get: (key: string) => string; } ->{ set: (key: string) => 'foobar', get: (key: string) => 'foobar' } : { set: (key: string) => string; get: (key: string) => string; } +>e : { get: (key: string) => string; set: (key: string) => string; } +>{ get: (key: string) => 'foobar', set: (key: string) => 'foobar' } : { get: (key: string) => string; set: (key: string) => string; } - set: (key: string) => 'foobar', ->set : (key: string) => string + get: (key: string) => 'foobar', +>get : (key: string) => string >(key: string) => 'foobar' : (key: string) => string >key : string >'foobar' : "foobar" - get: (key: string) => 'foobar' ->get : (key: string) => string + set: (key: string) => 'foobar' +>set : (key: string) => string >(key: string) => 'foobar' : (key: string) => string >key : string >'foobar' : "foobar" @@ -72,43 +72,43 @@ const bar = d['hello']; }; e['hello']; >e['hello'] : any ->e : { set: (key: string) => string; get: (key: string) => string; } +>e : { get: (key: string) => string; set: (key: string) => string; } >'hello' : "hello" e['hello'] = 'modified'; >e['hello'] = 'modified' : "modified" >e['hello'] : any ->e : { set: (key: string) => string; get: (key: string) => string; } +>e : { get: (key: string) => string; set: (key: string) => string; } >'hello' : "hello" >'modified' : "modified" e['hello'] += 1; >e['hello'] += 1 : any >e['hello'] : any ->e : { set: (key: string) => string; get: (key: string) => string; } +>e : { get: (key: string) => string; set: (key: string) => string; } >'hello' : "hello" >1 : 1 e['hello'] ++; >e['hello'] ++ : number >e['hello'] : any ->e : { set: (key: string) => string; get: (key: string) => string; } +>e : { get: (key: string) => string; set: (key: string) => string; } >'hello' : "hello" } { let e = { ->e : { set: (key: string) => string; get: (key: string, value: string) => string; } ->{ set: (key: string) => 'foobar', get: (key: string, value: string) => 'foobar' } : { set: (key: string) => string; get: (key: string, value: string) => string; } +>e : { get: (key: string) => string; set: (key: string, value: string) => string; } +>{ get: (key: string) => 'foobar', set: (key: string, value: string) => 'foobar' } : { get: (key: string) => string; set: (key: string, value: string) => string; } - set: (key: string) => 'foobar', ->set : (key: string) => string + get: (key: string) => 'foobar', +>get : (key: string) => string >(key: string) => 'foobar' : (key: string) => string >key : string >'foobar' : "foobar" - get: (key: string, value: string) => 'foobar' ->get : (key: string, value: string) => string + set: (key: string, value: string) => 'foobar' +>set : (key: string, value: string) => string >(key: string, value: string) => 'foobar' : (key: string, value: string) => string >key : string >value : string @@ -117,43 +117,43 @@ const bar = d['hello']; }; e['hello']; >e['hello'] : any ->e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>e : { get: (key: string) => string; set: (key: string, value: string) => string; } >'hello' : "hello" e['hello'] = 'modified'; >e['hello'] = 'modified' : "modified" >e['hello'] : any ->e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>e : { get: (key: string) => string; set: (key: string, value: string) => string; } >'hello' : "hello" >'modified' : "modified" e['hello'] += 1; >e['hello'] += 1 : any >e['hello'] : any ->e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>e : { get: (key: string) => string; set: (key: string, value: string) => string; } >'hello' : "hello" >1 : 1 e['hello'] ++; >e['hello'] ++ : number >e['hello'] : any ->e : { set: (key: string) => string; get: (key: string, value: string) => string; } +>e : { get: (key: string) => string; set: (key: string, value: string) => string; } >'hello' : "hello" } { let e = { ->e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } ->{ set: (key: "hello" | "world") => 'foobar', get: (key: "hello" | "world", value: string) => 'foobar' } : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; } +>{ get: (key: "hello" | "world") => 'foobar', set: (key: "hello" | "world", value: string) => 'foobar' } : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; } - set: (key: "hello" | "world") => 'foobar', ->set : (key: "hello" | "world") => string + get: (key: "hello" | "world") => 'foobar', +>get : (key: "hello" | "world") => string >(key: "hello" | "world") => 'foobar' : (key: "hello" | "world") => string >key : "hello" | "world" >'foobar' : "foobar" - get: (key: "hello" | "world", value: string) => 'foobar' ->get : (key: "hello" | "world", value: string) => string + set: (key: "hello" | "world", value: string) => 'foobar' +>set : (key: "hello" | "world", value: string) => string >(key: "hello" | "world", value: string) => 'foobar' : (key: "hello" | "world", value: string) => string >key : "hello" | "world" >value : string @@ -162,27 +162,169 @@ const bar = d['hello']; }; e['hello']; >e['hello'] : any ->e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; } >'hello' : "hello" e['hello'] = 'modified'; >e['hello'] = 'modified' : "modified" >e['hello'] : any ->e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; } >'hello' : "hello" >'modified' : "modified" e['hello'] += 1; >e['hello'] += 1 : any >e['hello'] : any ->e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; } >'hello' : "hello" >1 : 1 e['hello'] ++; >e['hello'] ++ : number >e['hello'] : any ->e : { set: (key: "hello" | "world") => string; get: (key: "hello" | "world", value: string) => string; } +>e : { get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; } +>'hello' : "hello" +} + +{ + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello']; +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] : any +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} }) : { get: (key: string) => string; set: (key: string, value: string) => void; } +>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; } +>get : (key: string) => string +>(key: string) => 'hello' : (key: string) => string +>key : string +>'hello' : "hello" +>set : (key: string, value: string) => void +>(key: string, value: string) => {} : (key: string, value: string) => void +>key : string +>value : string +>'hello' : "hello" + + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified'; +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified' : "modified" +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] : any +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} }) : { get: (key: string) => string; set: (key: string, value: string) => void; } +>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; } +>get : (key: string) => string +>(key: string) => 'hello' : (key: string) => string +>key : string +>'hello' : "hello" +>set : (key: string, value: string) => void +>(key: string, value: string) => {} : (key: string, value: string) => void +>key : string +>value : string +>'hello' : "hello" +>'modified' : "modified" + + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1; +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1 : any +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] : any +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} }) : { get: (key: string) => string; set: (key: string, value: string) => void; } +>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; } +>get : (key: string) => string +>(key: string) => 'hello' : (key: string) => string +>key : string +>'hello' : "hello" +>set : (key: string, value: string) => void +>(key: string, value: string) => {} : (key: string, value: string) => void +>key : string +>value : string +>'hello' : "hello" +>1 : 1 + + ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++; +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++ : number +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] : any +>({ get: (key: string) => 'hello', set: (key: string, value: string) => {} }) : { get: (key: string) => string; set: (key: string, value: string) => void; } +>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; } +>get : (key: string) => string +>(key: string) => 'hello' : (key: string) => string +>key : string +>'hello' : "hello" +>set : (key: string, value: string) => void +>(key: string, value: string) => {} : (key: string, value: string) => void +>key : string +>value : string +>'hello' : "hello" +} + +{ + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello']; +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] : any +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }) : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; } +>{ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } } : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; } +>foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; } +>get : (key: string) => string +>(key: string) => 'hello' : (key: string) => string +>key : string +>'hello' : "hello" +>set : (key: string, value: string) => void +>(key: string, value: string) => {} : (key: string, value: string) => void +>key : string +>value : string +>foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>'hello' : "hello" + + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified'; +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified' : "modified" +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] : any +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }) : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; } +>{ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } } : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; } +>foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; } +>get : (key: string) => string +>(key: string) => 'hello' : (key: string) => string +>key : string +>'hello' : "hello" +>set : (key: string, value: string) => void +>(key: string, value: string) => {} : (key: string, value: string) => void +>key : string +>value : string +>foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>'hello' : "hello" +>'modified' : "modified" + + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1; +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1 : any +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] : any +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }) : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; } +>{ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } } : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; } +>foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; } +>get : (key: string) => string +>(key: string) => 'hello' : (key: string) => string +>key : string +>'hello' : "hello" +>set : (key: string, value: string) => void +>(key: string, value: string) => {} : (key: string, value: string) => void +>key : string +>value : string +>foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>'hello' : "hello" +>1 : 1 + + ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++; +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++ : number +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] : any +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }) : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; } +>{ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } } : { foo: { get: (key: string) => string; set: (key: string, value: string) => void; }; } +>foo : { get: (key: string) => string; set: (key: string, value: string) => void; } +>{ get: (key: string) => 'hello', set: (key: string, value: string) => {} } : { get: (key: string) => string; set: (key: string, value: string) => void; } +>get : (key: string) => string +>(key: string) => 'hello' : (key: string) => string +>key : string +>'hello' : "hello" +>set : (key: string, value: string) => void +>(key: string, value: string) => {} : (key: string, value: string) => void +>key : string +>value : string +>foo : { get: (key: string) => string; set: (key: string, value: string) => void; } >'hello' : "hello" } From 9c6fac3aa6dbcc2dc7c07db3d2c0c463a6b0c3f2 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 16:02:47 -0700 Subject: [PATCH 08/11] Short-circuit stringification on 'undefined'. --- src/compiler/utilities.ts | 7 +++++-- src/services/navigationBar.ts | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7ee5dcd8278e0..ff43e8797683e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4244,9 +4244,12 @@ namespace ts { export function tryGetPropertyAccessOrIdentifierToString(expr: Expression): string | undefined { if (isPropertyAccessExpression(expr)) { - return tryGetPropertyAccessOrIdentifierToString(expr.expression) + "." + expr.name; + const baseStr = tryGetPropertyAccessOrIdentifierToString(expr.expression); + if (baseStr !== undefined) { + return baseStr + "." + expr.name; + } } - if (isIdentifier(expr)) { + else if (isIdentifier(expr)) { return unescapeLeadingUnderscores(expr.escapedText); } return undefined; diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 49310ef827f1e..ba369f975fbe5 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -901,6 +901,7 @@ namespace ts.NavigationBar { return ""; } + // See also 'tryGetPropertyAccessOrIdentifierToString' function getCalledExpressionName(expr: Expression): string | undefined { if (isIdentifier(expr)) { return expr.text; From 7d0d06275dfb91d30f1fa0d0d4aae4e4ced69ac9 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 2 Nov 2019 16:03:20 -0700 Subject: [PATCH 09/11] Accepted baselines. --- ...noImplicitAnyStringIndexerOnObject.errors.txt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt index cceaee0745a81..9a4129cc56555 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt @@ -20,10 +20,10 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(49,3): error TS7052: tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(50,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(51,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(52,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(56,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(57,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(58,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(59,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(56,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(57,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(58,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(59,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(65,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'. Property 'b' does not exist on type '{ a: number; }'. tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(69,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'. @@ -137,16 +137,16 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538: { ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello']; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get' ? ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'undefined.[object Object].set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? } const o = { a: 0 }; From 409b6a2b545c0b4c631467b0355f8426b6c825af Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 4 Nov 2019 08:19:03 -0800 Subject: [PATCH 10/11] Remove space. --- src/compiler/diagnosticMessages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d76219e90a708..3fb8d2d7733d4 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4502,7 +4502,7 @@ "category": "Error", "code": 7051 }, - "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}' ?": { + "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}'?": { "category": "Error", "code": 7052 }, From 321efc1fe678c2d5180738ffdf4c67802e11762c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 4 Nov 2019 08:19:27 -0800 Subject: [PATCH 11/11] Accepted baselines. --- ...mplicitAnyStringIndexerOnObject.errors.txt | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt index 9a4129cc56555..729c8236abd42 100644 --- a/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt +++ b/tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt @@ -1,29 +1,29 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(1,9): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{}'. Property 'hello' does not exist on type '{}'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(7,1): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(8,13): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(7,1): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(8,13): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get'? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(13,13): error TS7053: Element implicitly has an 'any' type because expression of type '"hello"' can't be used to index type '{ set: (key: string) => string; }'. Property 'hello' does not exist on type '{ set: (key: string) => string; }'. -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(22,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(23,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(31,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(32,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(34,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(43,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(44,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(45,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(49,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(50,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(51,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(52,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(56,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(57,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(58,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? -tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(59,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(20,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.get'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(21,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(22,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(23,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(31,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.get'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(32,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(33,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(34,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.get'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(43,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(44,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(45,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(49,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(50,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(51,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(52,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(56,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(57,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(58,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? +tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(59,3): error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(65,1): error TS7053: Element implicitly has an 'any' type because expression of type '"a" | "b" | "c"' can't be used to index type '{ a: number; }'. Property 'b' does not exist on type '{ a: number; }'. tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(69,1): error TS7053: Element implicitly has an 'any' type because expression of type '"c"' can't be used to index type '{ a: number; }'. @@ -49,10 +49,10 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538: }; c['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get'? const foo = c['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; }' has no index signature. Did you mean to call 'c.get'? var d = { set: (key: string) => 'foobar' @@ -69,16 +69,16 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538: }; e['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.get'? e['hello'] = 'modified'; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'? e['hello'] += 1; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'? e['hello'] ++; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string) => string; }' has no index signature. Did you mean to call 'e.set'? } { @@ -88,16 +88,16 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538: }; e['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.get'? e['hello'] = 'modified'; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'? e['hello'] += 1; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'? e['hello'] ++; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => string; }' has no index signature. Did you mean to call 'e.set'? } { @@ -107,46 +107,46 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538: }; e['hello']; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.get'? e['hello'] = 'modified'; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'? e['hello'] += 1; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'? e['hello'] ++; ~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: "hello" | "world") => string; set: (key: "hello" | "world", value: string) => string; }' has no index signature. Did you mean to call 'e.set'? } { ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello']; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get'? ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] += 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? ({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] ++; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? } { ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello']; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'get'? ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] += 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? ({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] ++; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set' ? +!!! error TS7052: Element implicitly has an 'any' type because type '{ get: (key: string) => string; set: (key: string, value: string) => void; }' has no index signature. Did you mean to call 'set'? } const o = { a: 0 };