Skip to content

Commit 0a623f8

Browse files
committed
Merge pull request #8822 from Microsoft/excess-property-check-numeric-indexers
Excess property check numeric indexers
2 parents 6304d79 + 42c17e1 commit 0a623f8

File tree

38 files changed

+301
-161
lines changed

38 files changed

+301
-161
lines changed

src/compiler/checker.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -6034,9 +6034,10 @@ namespace ts {
60346034
function isKnownProperty(type: Type, name: string): boolean {
60356035
if (type.flags & TypeFlags.ObjectType) {
60366036
const resolved = resolveStructuredTypeMembers(type);
6037-
if ((relation === assignableRelation || relation === comparableRelation) &&
6038-
(type === globalObjectType || isEmptyObjectType(resolved)) ||
6039-
resolved.stringIndexInfo || resolved.numberIndexInfo || getPropertyOfType(type, name)) {
6037+
if ((relation === assignableRelation || relation === comparableRelation) && (type === globalObjectType || isEmptyObjectType(resolved)) ||
6038+
resolved.stringIndexInfo ||
6039+
(resolved.numberIndexInfo && isNumericLiteralName(name)) ||
6040+
getPropertyOfType(type, name)) {
60406041
return true;
60416042
}
60426043
}
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
//// [computedPropertyNamesContextualType7_ES5.ts]
22
interface I<T> {
3-
[s: number]: T;
3+
[n: number]: T;
4+
}
5+
interface J<T> {
6+
[s: string]: T;
47
}
58

6-
declare function foo<T>(obj: I<T>): T
9+
declare function foo<T>(obj: I<T>): T;
10+
declare function g<T>(obj: J<T>): T;
711

812
foo({
9-
p: "",
1013
0: () => { },
1114
["hi" + "bye"]: true,
1215
[0 + 1]: 0,
1316
[+"hi"]: [0]
14-
});
17+
});
18+
19+
g({ p: "" });
20+
1521

1622
//// [computedPropertyNamesContextualType7_ES5.js]
1723
foo((_a = {
18-
p: "",
1924
0: function () { }
2025
},
2126
_a["hi" + "bye"] = true,
2227
_a[0 + 1] = 0,
2328
_a[+"hi"] = [0],
2429
_a
2530
));
31+
g({ p: "" });
2632
var _a;

tests/baselines/reference/computedPropertyNamesContextualType7_ES5.symbols

+30-12
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,45 @@ interface I<T> {
33
>I : Symbol(I, Decl(computedPropertyNamesContextualType7_ES5.ts, 0, 0))
44
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 0, 12))
55

6-
[s: number]: T;
7-
>s : Symbol(s, Decl(computedPropertyNamesContextualType7_ES5.ts, 1, 5))
6+
[n: number]: T;
7+
>n : Symbol(n, Decl(computedPropertyNamesContextualType7_ES5.ts, 1, 5))
88
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 0, 12))
99
}
10+
interface J<T> {
11+
>J : Symbol(J, Decl(computedPropertyNamesContextualType7_ES5.ts, 2, 1))
12+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 3, 12))
1013

11-
declare function foo<T>(obj: I<T>): T
12-
>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES5.ts, 2, 1))
13-
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 21))
14-
>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 24))
14+
[s: string]: T;
15+
>s : Symbol(s, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 5))
16+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 3, 12))
17+
}
18+
19+
declare function foo<T>(obj: I<T>): T;
20+
>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES5.ts, 5, 1))
21+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 21))
22+
>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 24))
1523
>I : Symbol(I, Decl(computedPropertyNamesContextualType7_ES5.ts, 0, 0))
16-
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 21))
17-
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 4, 21))
24+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 21))
25+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 21))
1826

19-
foo({
20-
>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES5.ts, 2, 1))
27+
declare function g<T>(obj: J<T>): T;
28+
>g : Symbol(g, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 38))
29+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 8, 19))
30+
>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES5.ts, 8, 22))
31+
>J : Symbol(J, Decl(computedPropertyNamesContextualType7_ES5.ts, 2, 1))
32+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 8, 19))
33+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES5.ts, 8, 19))
2134

22-
p: "",
23-
>p : Symbol(p, Decl(computedPropertyNamesContextualType7_ES5.ts, 6, 5))
35+
foo({
36+
>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES5.ts, 5, 1))
2437

2538
0: () => { },
2639
["hi" + "bye"]: true,
2740
[0 + 1]: 0,
2841
[+"hi"]: [0]
2942
});
43+
44+
g({ p: "" });
45+
>g : Symbol(g, Decl(computedPropertyNamesContextualType7_ES5.ts, 7, 38))
46+
>p : Symbol(p, Decl(computedPropertyNamesContextualType7_ES5.ts, 17, 3))
47+

tests/baselines/reference/computedPropertyNamesContextualType7_ES5.types

+29-9
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,39 @@ interface I<T> {
33
>I : I<T>
44
>T : T
55

6-
[s: number]: T;
7-
>s : number
6+
[n: number]: T;
7+
>n : number
8+
>T : T
9+
}
10+
interface J<T> {
11+
>J : J<T>
12+
>T : T
13+
14+
[s: string]: T;
15+
>s : string
816
>T : T
917
}
1018

11-
declare function foo<T>(obj: I<T>): T
19+
declare function foo<T>(obj: I<T>): T;
1220
>foo : <T>(obj: I<T>) => T
1321
>T : T
1422
>obj : I<T>
1523
>I : I<T>
1624
>T : T
1725
>T : T
1826

27+
declare function g<T>(obj: J<T>): T;
28+
>g : <T>(obj: J<T>) => T
29+
>T : T
30+
>obj : J<T>
31+
>J : J<T>
32+
>T : T
33+
>T : T
34+
1935
foo({
20-
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : (() => void) | number | number[]
36+
>foo({ 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : (() => void) | number | number[]
2137
>foo : <T>(obj: I<T>) => T
22-
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | (() => void) | boolean | number | number[]; [x: number]: (() => void) | number | number[]; 0: () => void; p: string; }
23-
24-
p: "",
25-
>p : string
26-
>"" : string
38+
>{ 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: (() => void) | boolean | number | number[]; [x: number]: (() => void) | number | number[]; 0: () => void; }
2739

2840
0: () => { },
2941
>() => { } : () => void
@@ -47,3 +59,11 @@ foo({
4759
>0 : number
4860

4961
});
62+
63+
g({ p: "" });
64+
>g({ p: "" }) : string
65+
>g : <T>(obj: J<T>) => T
66+
>{ p: "" } : { p: string; }
67+
>p : string
68+
>"" : string
69+
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,29 @@
11
//// [computedPropertyNamesContextualType7_ES6.ts]
22
interface I<T> {
3-
[s: number]: T;
3+
[n: number]: T;
4+
}
5+
interface J<T> {
6+
[s: string]: T;
47
}
58

6-
declare function foo<T>(obj: I<T>): T
9+
declare function foo<T>(obj: I<T>): T;
10+
declare function g<T>(obj: J<T>): T;
711

812
foo({
9-
p: "",
1013
0: () => { },
1114
["hi" + "bye"]: true,
1215
[0 + 1]: 0,
1316
[+"hi"]: [0]
14-
});
17+
});
18+
19+
g({ p: "" });
20+
1521

1622
//// [computedPropertyNamesContextualType7_ES6.js]
1723
foo({
18-
p: "",
1924
0: () => { },
2025
["hi" + "bye"]: true,
2126
[0 + 1]: 0,
2227
[+"hi"]: [0]
2328
});
29+
g({ p: "" });

tests/baselines/reference/computedPropertyNamesContextualType7_ES6.symbols

+30-12
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,45 @@ interface I<T> {
33
>I : Symbol(I, Decl(computedPropertyNamesContextualType7_ES6.ts, 0, 0))
44
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 0, 12))
55

6-
[s: number]: T;
7-
>s : Symbol(s, Decl(computedPropertyNamesContextualType7_ES6.ts, 1, 5))
6+
[n: number]: T;
7+
>n : Symbol(n, Decl(computedPropertyNamesContextualType7_ES6.ts, 1, 5))
88
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 0, 12))
99
}
10+
interface J<T> {
11+
>J : Symbol(J, Decl(computedPropertyNamesContextualType7_ES6.ts, 2, 1))
12+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 3, 12))
1013

11-
declare function foo<T>(obj: I<T>): T
12-
>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES6.ts, 2, 1))
13-
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 21))
14-
>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 24))
14+
[s: string]: T;
15+
>s : Symbol(s, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 5))
16+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 3, 12))
17+
}
18+
19+
declare function foo<T>(obj: I<T>): T;
20+
>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES6.ts, 5, 1))
21+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 21))
22+
>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 24))
1523
>I : Symbol(I, Decl(computedPropertyNamesContextualType7_ES6.ts, 0, 0))
16-
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 21))
17-
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 4, 21))
24+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 21))
25+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 21))
1826

19-
foo({
20-
>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES6.ts, 2, 1))
27+
declare function g<T>(obj: J<T>): T;
28+
>g : Symbol(g, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 38))
29+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 8, 19))
30+
>obj : Symbol(obj, Decl(computedPropertyNamesContextualType7_ES6.ts, 8, 22))
31+
>J : Symbol(J, Decl(computedPropertyNamesContextualType7_ES6.ts, 2, 1))
32+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 8, 19))
33+
>T : Symbol(T, Decl(computedPropertyNamesContextualType7_ES6.ts, 8, 19))
2134

22-
p: "",
23-
>p : Symbol(p, Decl(computedPropertyNamesContextualType7_ES6.ts, 6, 5))
35+
foo({
36+
>foo : Symbol(foo, Decl(computedPropertyNamesContextualType7_ES6.ts, 5, 1))
2437

2538
0: () => { },
2639
["hi" + "bye"]: true,
2740
[0 + 1]: 0,
2841
[+"hi"]: [0]
2942
});
43+
44+
g({ p: "" });
45+
>g : Symbol(g, Decl(computedPropertyNamesContextualType7_ES6.ts, 7, 38))
46+
>p : Symbol(p, Decl(computedPropertyNamesContextualType7_ES6.ts, 17, 3))
47+

tests/baselines/reference/computedPropertyNamesContextualType7_ES6.types

+29-9
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,39 @@ interface I<T> {
33
>I : I<T>
44
>T : T
55

6-
[s: number]: T;
7-
>s : number
6+
[n: number]: T;
7+
>n : number
8+
>T : T
9+
}
10+
interface J<T> {
11+
>J : J<T>
12+
>T : T
13+
14+
[s: string]: T;
15+
>s : string
816
>T : T
917
}
1018

11-
declare function foo<T>(obj: I<T>): T
19+
declare function foo<T>(obj: I<T>): T;
1220
>foo : <T>(obj: I<T>) => T
1321
>T : T
1422
>obj : I<T>
1523
>I : I<T>
1624
>T : T
1725
>T : T
1826

27+
declare function g<T>(obj: J<T>): T;
28+
>g : <T>(obj: J<T>) => T
29+
>T : T
30+
>obj : J<T>
31+
>J : J<T>
32+
>T : T
33+
>T : T
34+
1935
foo({
20-
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : (() => void) | number | number[]
36+
>foo({ 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : (() => void) | number | number[]
2137
>foo : <T>(obj: I<T>) => T
22-
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | (() => void) | boolean | number | number[]; [x: number]: (() => void) | number | number[]; 0: () => void; p: string; }
23-
24-
p: "",
25-
>p : string
26-
>"" : string
38+
>{ 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: (() => void) | boolean | number | number[]; [x: number]: (() => void) | number | number[]; 0: () => void; }
2739

2840
0: () => { },
2941
>() => { } : () => void
@@ -47,3 +59,11 @@ foo({
4759
>0 : number
4860

4961
});
62+
63+
g({ p: "" });
64+
>g({ p: "" }) : string
65+
>g : <T>(obj: J<T>) => T
66+
>{ p: "" } : { p: string; }
67+
>p : string
68+
>"" : string
69+

tests/baselines/reference/indexSignaturesInferentialTyping.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ function foo<T>(items: { [index: number]: T }): T { return undefined; }
33
function bar<T>(items: { [index: string]: T }): T { return undefined; }
44

55
var x1 = foo({ 0: 0, 1: 1 }); // type should be number
6-
var x2 = foo({ zero: 0, one: 1 });
7-
var x3 = bar({ 0: 0, 1: 1 });
8-
var x4 = bar({ zero: 0, one: 1 }); // type should be number
6+
var x2 = bar({ 0: 0, 1: 1 });
7+
var x3 = bar({ zero: 0, one: 1 }); // type should be number
98

109

1110
//// [indexSignaturesInferentialTyping.js]
1211
function foo(items) { return undefined; }
1312
function bar(items) { return undefined; }
1413
var x1 = foo({ 0: 0, 1: 1 }); // type should be number
15-
var x2 = foo({ zero: 0, one: 1 });
16-
var x3 = bar({ 0: 0, 1: 1 });
17-
var x4 = bar({ zero: 0, one: 1 }); // type should be number
14+
var x2 = bar({ 0: 0, 1: 1 });
15+
var x3 = bar({ zero: 0, one: 1 }); // type should be number

tests/baselines/reference/indexSignaturesInferentialTyping.symbols

+5-11
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,13 @@ var x1 = foo({ 0: 0, 1: 1 }); // type should be number
2121
>x1 : Symbol(x1, Decl(indexSignaturesInferentialTyping.ts, 3, 3))
2222
>foo : Symbol(foo, Decl(indexSignaturesInferentialTyping.ts, 0, 0))
2323

24-
var x2 = foo({ zero: 0, one: 1 });
24+
var x2 = bar({ 0: 0, 1: 1 });
2525
>x2 : Symbol(x2, Decl(indexSignaturesInferentialTyping.ts, 4, 3))
26-
>foo : Symbol(foo, Decl(indexSignaturesInferentialTyping.ts, 0, 0))
27-
>zero : Symbol(zero, Decl(indexSignaturesInferentialTyping.ts, 4, 14))
28-
>one : Symbol(one, Decl(indexSignaturesInferentialTyping.ts, 4, 23))
29-
30-
var x3 = bar({ 0: 0, 1: 1 });
31-
>x3 : Symbol(x3, Decl(indexSignaturesInferentialTyping.ts, 5, 3))
3226
>bar : Symbol(bar, Decl(indexSignaturesInferentialTyping.ts, 0, 71))
3327

34-
var x4 = bar({ zero: 0, one: 1 }); // type should be number
35-
>x4 : Symbol(x4, Decl(indexSignaturesInferentialTyping.ts, 6, 3))
28+
var x3 = bar({ zero: 0, one: 1 }); // type should be number
29+
>x3 : Symbol(x3, Decl(indexSignaturesInferentialTyping.ts, 5, 3))
3630
>bar : Symbol(bar, Decl(indexSignaturesInferentialTyping.ts, 0, 71))
37-
>zero : Symbol(zero, Decl(indexSignaturesInferentialTyping.ts, 6, 14))
38-
>one : Symbol(one, Decl(indexSignaturesInferentialTyping.ts, 6, 23))
31+
>zero : Symbol(zero, Decl(indexSignaturesInferentialTyping.ts, 5, 14))
32+
>one : Symbol(one, Decl(indexSignaturesInferentialTyping.ts, 5, 23))
3933

0 commit comments

Comments
 (0)