Skip to content

Commit dccfdbb

Browse files
committed
Keep showing error when property doesn't exist on type
1 parent 4faa7b2 commit dccfdbb

8 files changed

+163
-8
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12703,6 +12703,7 @@ namespace ts {
1270312703
if (accessExpression && !isConstEnumObjectType(objectType)) {
1270412704
if (isObjectLiteralType(objectType)) {
1270512705
if (indexType.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral)) {
12706+
diagnostics.add(createDiagnosticForNode(accessExpression, Diagnostics.Property_0_does_not_exist_on_type_1, (indexType as StringLiteralType).value, typeToString(objectType)))
1270612707
return undefinedType;
1270712708
}
1270812709
else if (indexType.flags & (TypeFlags.Number | TypeFlags.String)) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
tests/cases/conformance/types/members/augmentedTypeBracketAccessIndexSignature.ts(12,9): error TS2339: Property '0' does not exist on type '{}'.
2+
3+
4+
==== tests/cases/conformance/types/members/augmentedTypeBracketAccessIndexSignature.ts (1 errors) ====
5+
interface Foo { a }
6+
interface Bar { b }
7+
8+
interface Object {
9+
[n: number]: Foo;
10+
}
11+
12+
interface Function {
13+
[n: number]: Bar;
14+
}
15+
16+
var a = {}[0]; // Should be Foo
17+
~~~~~
18+
!!! error TS2339: Property '0' does not exist on type '{}'.
19+
var b = (() => { })[0]; // Should be Bar

tests/baselines/reference/augmentedTypeBracketAccessIndexSignature.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ var a = {}[0]; // Should be Foo
2222
>0 : 0
2323

2424
var b = (() => { })[0]; // Should be Bar
25-
>b : error
26-
>(() => { })[0] : error
25+
>b : any
26+
>(() => { })[0] : any
2727
>(() => { }) : () => void
2828
>() => { } : () => void
2929
>0 : 0
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
tests/cases/compiler/indexedAccessWithObjectLiteral.ts(34,10): error TS2339: Property 'z' does not exist on type '{ a: number; b: string; c: boolean; }'.
2+
3+
4+
==== tests/cases/compiler/indexedAccessWithObjectLiteral.ts (1 errors) ====
5+
function foo (id: string) {
6+
return {
7+
a: 1,
8+
b: "",
9+
c: true
10+
}[id]
11+
}
12+
13+
function bar (id: 'a' | 'b') {
14+
return {
15+
a: 1,
16+
b: "",
17+
c: false
18+
}[id]
19+
}
20+
21+
function baz (id: '1' | '2') {
22+
return {
23+
1: 1,
24+
2: "",
25+
3: false
26+
}[id]
27+
}
28+
29+
function qux (id: 1 | 2) {
30+
return {
31+
1: 1,
32+
2: "",
33+
3: false
34+
}[id]
35+
}
36+
37+
function quux (id: 'a' | 'b' | 'z') {
38+
return {
39+
~
40+
a: 1,
41+
~~~~~~~~~~~
42+
b: "",
43+
~~~~~~~~~~~~
44+
c: false
45+
~~~~~~~~~~~~~~
46+
}[id]
47+
~~~~~~~
48+
!!! error TS2339: Property 'z' does not exist on type '{ a: number; b: string; c: boolean; }'.
49+
}
50+
51+
function corge(id: string) {
52+
return ({
53+
a: 123,
54+
b: ""
55+
} as Record<string, number | string>)[id]
56+
}
57+
58+
function grault(id: string) {
59+
return ({
60+
a: 123,
61+
b: ""
62+
} as { [k: string]: string | number})[id]
63+
}
64+

tests/baselines/reference/noImplicitAnyIndexing.errors.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
tests/cases/compiler/noImplicitAnyIndexing.ts(12,37): error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
2+
tests/cases/compiler/noImplicitAnyIndexing.ts(19,9): error TS2339: Property 'hi' does not exist on type '{}'.
3+
tests/cases/compiler/noImplicitAnyIndexing.ts(22,9): error TS2339: Property '10' does not exist on type '{}'.
24
tests/cases/compiler/noImplicitAnyIndexing.ts(30,10): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{}'.
35

46

5-
==== tests/cases/compiler/noImplicitAnyIndexing.ts (2 errors) ====
7+
==== tests/cases/compiler/noImplicitAnyIndexing.ts (4 errors) ====
68
enum MyEmusEnum {
79
emu
810
}
@@ -24,9 +26,13 @@ tests/cases/compiler/noImplicitAnyIndexing.ts(30,10): error TS7053: Element impl
2426

2527
// Should report an implicit 'any'.
2628
var x = {}["hi"];
29+
~~~~~~~~
30+
!!! error TS2339: Property 'hi' does not exist on type '{}'.
2731

2832
// Should report an implicit 'any'.
2933
var y = {}[10];
34+
~~~~~~
35+
!!! error TS2339: Property '10' does not exist on type '{}'.
3036

3137

3238
var hi: any = "hi";
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
tests/cases/compiler/noImplicitAnyIndexingSuppressed.ts(19,9): error TS2339: Property 'hi' does not exist on type '{}'.
2+
tests/cases/compiler/noImplicitAnyIndexingSuppressed.ts(22,9): error TS2339: Property '10' does not exist on type '{}'.
3+
4+
5+
==== tests/cases/compiler/noImplicitAnyIndexingSuppressed.ts (2 errors) ====
6+
enum MyEmusEnum {
7+
emu
8+
}
9+
10+
// Should be okay; should be a string.
11+
var strRepresentation1 = MyEmusEnum[0]
12+
13+
// Should be okay; should be a string.
14+
var strRepresentation2 = MyEmusEnum[MyEmusEnum.emu]
15+
16+
// Should be okay, as we suppress implicit 'any' property access checks
17+
var strRepresentation3 = MyEmusEnum["monehh"];
18+
19+
// Should be okay; should be a MyEmusEnum
20+
var strRepresentation4 = MyEmusEnum["emu"];
21+
22+
23+
// Should be okay, as we suppress implicit 'any' property access checks
24+
var x = {}["hi"];
25+
~~~~~~~~
26+
!!! error TS2339: Property 'hi' does not exist on type '{}'.
27+
28+
// Should be okay, as we suppress implicit 'any' property access checks
29+
var y = {}[10];
30+
~~~~~~
31+
!!! error TS2339: Property '10' does not exist on type '{}'.
32+
33+
var hi: any = "hi";
34+
35+
var emptyObj = {};
36+
37+
// Should be okay, as we suppress implicit 'any' property access checks
38+
var z1 = emptyObj[hi];
39+
var z2 = (<any>emptyObj)[hi];
40+
41+
interface MyMap<T> {
42+
[key: string]: T;
43+
}
44+
45+
var m: MyMap<number> = {
46+
"0": 0,
47+
"1": 1,
48+
"2": 2,
49+
"Okay that's enough for today.": NaN
50+
};
51+
52+
var mResult1 = m[MyEmusEnum.emu];
53+
var mResult2 = m[MyEmusEnum[MyEmusEnum.emu]];
54+
var mResult3 = m[hi];
55+
56+

tests/baselines/reference/noImplicitAnyIndexingSuppressed.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ var strRepresentation2 = MyEmusEnum[MyEmusEnum.emu]
2424

2525
// Should be okay, as we suppress implicit 'any' property access checks
2626
var strRepresentation3 = MyEmusEnum["monehh"];
27-
>strRepresentation3 : error
28-
>MyEmusEnum["monehh"] : error
27+
>strRepresentation3 : any
28+
>MyEmusEnum["monehh"] : any
2929
>MyEmusEnum : typeof MyEmusEnum
3030
>"monehh" : "monehh"
3131

@@ -61,8 +61,8 @@ var emptyObj = {};
6161

6262
// Should be okay, as we suppress implicit 'any' property access checks
6363
var z1 = emptyObj[hi];
64-
>z1 : error
65-
>emptyObj[hi] : error
64+
>z1 : any
65+
>emptyObj[hi] : any
6666
>emptyObj : {}
6767
>hi : any
6868

tests/baselines/reference/noImplicitAnyStringIndexerOnObject.errors.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(1,9): error TS2339: Property 'hello' does not exist on type '{}'.
12
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'?
23
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'?
34
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; }'.
@@ -14,9 +15,11 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(42,3): error TS7052:
1415
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'?
1516
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'?
1617
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'?
18+
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(49,3): error TS2339: Property 'hello' does not exist on type '{ get: (key: string) => string; set: (key: string, value: string) => void; }'.
1719
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'?
1820
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'?
1921
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'?
22+
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(56,3): error TS2339: Property 'hello' does not exist on type '{ get: (key: string) => string; set: (key: string, value: string) => void; }'.
2023
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'?
2124
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'?
2225
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'?
@@ -33,8 +36,10 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(81,1): error TS7053:
3336
tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538: Type 'Dog' cannot be used as an index type.
3437

3538

36-
==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (27 errors) ====
39+
==== tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts (30 errors) ====
3740
var a = {}["hello"];
41+
~~~~~~~~~~~
42+
!!! error TS2339: Property 'hello' does not exist on type '{}'.
3843
var b: string = { '': 'foo' }[''];
3944

4045
var c = {
@@ -114,6 +119,8 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538:
114119

115120
{
116121
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'];
122+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123+
!!! error TS2339: Property 'hello' does not exist on type '{ get: (key: string) => string; set: (key: string, value: string) => void; }'.
117124
({ get: (key: string) => 'hello', set: (key: string, value: string) => {} })['hello'] = 'modified';
118125
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
119126
!!! 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'?
@@ -127,6 +134,8 @@ tests/cases/compiler/noImplicitAnyStringIndexerOnObject.ts(93,5): error TS2538:
127134

128135
{
129136
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'];
137+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
138+
!!! error TS2339: Property 'hello' does not exist on type '{ get: (key: string) => string; set: (key: string, value: string) => void; }'.
130139
({ foo: { get: (key: string) => 'hello', set: (key: string, value: string) => {} } }).foo['hello'] = 'modified';
131140
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
132141
!!! 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'?

0 commit comments

Comments
 (0)