Skip to content

Commit ea33d6e

Browse files
committed
More precise Object.entries type declarations
We can leverage the new index type queries and indexed access types from microsoft#11929 to get better type inference for Object.entries.
1 parent 0e879c0 commit ea33d6e

File tree

6 files changed

+60
-19
lines changed

6 files changed

+60
-19
lines changed

src/lib/es2017.object.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ interface ObjectConstructor {
99
* Returns an array of key/values of the enumerable properties of an object
1010
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
1111
*/
12-
entries<T>(o: { [s: string]: T }): [string, T][];
12+
entries<T extends { [key: string]: any }, K extends keyof T>(o: T): [keyof T, T[K]][];
1313
entries(o: any): [string, any][];
14-
}
14+
}

tests/baselines/reference/useObjectValuesAndEntries1.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@ for (var x of Object.values(o)) {
66
let y = x;
77
}
88

9-
var entries = Object.entries(o);
10-
var entries1 = Object.entries(1); // <-- entries: [string, any][]
9+
var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][]
10+
var entries1 = Object.entries(1); // <-- entries: [string, any][]
11+
var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][]
12+
var entries3 = Object.entries({}) // [never, any][]
13+
1114

1215
//// [useObjectValuesAndEntries1.js]
1316
var o = { a: 1, b: 2 };
1417
for (var _i = 0, _a = Object.values(o); _i < _a.length; _i++) {
1518
var x = _a[_i];
1619
var y = x;
1720
}
18-
var entries = Object.entries(o);
21+
var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][]
1922
var entries1 = Object.entries(1); // <-- entries: [string, any][]
23+
var entries2 = Object.entries({ a: true, b: 2 }); // ['a' | 'b', number | boolean][]
24+
var entries3 = Object.entries({}); // [never, any][]

tests/baselines/reference/useObjectValuesAndEntries1.symbols

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ for (var x of Object.values(o)) {
1717
>x : Symbol(x, Decl(useObjectValuesAndEntries1.ts, 3, 8))
1818
}
1919

20-
var entries = Object.entries(o);
20+
var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][]
2121
>entries : Symbol(entries, Decl(useObjectValuesAndEntries1.ts, 7, 3))
2222
>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
2323
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
@@ -30,3 +30,17 @@ var entries1 = Object.entries(1); // <-- entries: [string, any][]
3030
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
3131
>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
3232

33+
var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][]
34+
>entries2 : Symbol(entries2, Decl(useObjectValuesAndEntries1.ts, 9, 3))
35+
>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
36+
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
37+
>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
38+
>a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 9, 31))
39+
>b : Symbol(b, Decl(useObjectValuesAndEntries1.ts, 9, 39))
40+
41+
var entries3 = Object.entries({}) // [never, any][]
42+
>entries3 : Symbol(entries3, Decl(useObjectValuesAndEntries1.ts, 10, 3))
43+
>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
44+
>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
45+
>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --))
46+

tests/baselines/reference/useObjectValuesAndEntries1.types

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,39 @@ for (var x of Object.values(o)) {
2121
>x : number
2222
}
2323

24-
var entries = Object.entries(o);
25-
>entries : [string, number][]
26-
>Object.entries(o) : [string, number][]
27-
>Object.entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
24+
var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][]
25+
>entries : ["a" | "b", number][]
26+
>Object.entries(o) : ["a" | "b", number][]
27+
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
2828
>Object : ObjectConstructor
29-
>entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
29+
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
3030
>o : { a: number; b: number; }
3131

3232
var entries1 = Object.entries(1); // <-- entries: [string, any][]
3333
>entries1 : [string, any][]
3434
>Object.entries(1) : [string, any][]
35-
>Object.entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
35+
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
3636
>Object : ObjectConstructor
37-
>entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
37+
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
3838
>1 : 1
3939

40+
var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][]
41+
>entries2 : ["a" | "b", number | boolean][]
42+
>Object.entries({a: true, b: 2}) : ["a" | "b", number | boolean][]
43+
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
44+
>Object : ObjectConstructor
45+
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
46+
>{a: true, b: 2} : { a: true; b: number; }
47+
>a : boolean
48+
>true : true
49+
>b : number
50+
>2 : 2
51+
52+
var entries3 = Object.entries({}) // [never, any][]
53+
>entries3 : [never, any][]
54+
>Object.entries({}) : [never, any][]
55+
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
56+
>Object : ObjectConstructor
57+
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
58+
>{} : {}
59+

tests/baselines/reference/useObjectValuesAndEntries4.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ for (var x of Object.values(o)) {
2222
}
2323

2424
var entries = Object.entries(o);
25-
>entries : [string, number][]
26-
>Object.entries(o) : [string, number][]
27-
>Object.entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
25+
>entries : ["a" | "b", number][]
26+
>Object.entries(o) : ["a" | "b", number][]
27+
>Object.entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
2828
>Object : ObjectConstructor
29-
>entries : { <T>(o: { [s: string]: T; }): [string, T][]; (o: any): [string, any][]; }
29+
>entries : { <T extends { [key: string]: any; }, K extends keyof T>(o: T): [keyof T, T[K]][]; (o: any): [string, any][]; }
3030
>o : { a: number; b: number; }
3131

tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@ for (var x of Object.values(o)) {
77
let y = x;
88
}
99

10-
var entries = Object.entries(o);
11-
var entries1 = Object.entries(1); // <-- entries: [string, any][]
10+
var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][]
11+
var entries1 = Object.entries(1); // <-- entries: [string, any][]
12+
var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][]
13+
var entries3 = Object.entries({}) // [never, any][]

0 commit comments

Comments
 (0)