From 5599d05252c3453714fa9d093f6db794cca93bb9 Mon Sep 17 00:00:00 2001 From: Ethan Resnick Date: Mon, 14 Nov 2016 20:51:28 -0500 Subject: [PATCH 1/3] Object.entries() types: fixup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Special case array. Because array instances are typed as implementing an interface that lists all their public methods, `keyof Array` returns all those method names as keys…even though they’re not actually enumerable at runtime. 2. Intersect keyof T with string, because `keyof T` can return `number | string` in some cases, whereas the entries’ keys will always be strings. --- src/lib/es2017.object.d.ts | 3 +- .../reference/useObjectValuesAndEntries1.js | 21 +++++-- .../useObjectValuesAndEntries1.symbols | 40 ++++++++---- .../useObjectValuesAndEntries1.types | 61 +++++++++++++------ .../useObjectValuesAndEntries4.symbols | 4 +- .../useObjectValuesAndEntries4.types | 8 +-- .../es2017/useObjectValuesAndEntries1.ts | 11 +++- 7 files changed, 104 insertions(+), 44 deletions(-) diff --git a/src/lib/es2017.object.d.ts b/src/lib/es2017.object.d.ts index c219f467ac985..1bae8513b4ed2 100644 --- a/src/lib/es2017.object.d.ts +++ b/src/lib/es2017.object.d.ts @@ -9,6 +9,7 @@ interface ObjectConstructor { * Returns an array of key/values of the enumerable properties of an object * @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. */ - entries(o: T): [keyof T, T[K]][]; + entries(o: Array): [string, T][]; + entries(o: T): [keyof T & string, T[K]][]; entries(o: any): [string, any][]; } diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.js b/tests/baselines/reference/useObjectValuesAndEntries1.js index 728e14e746363..d6d538e239464 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.js +++ b/tests/baselines/reference/useObjectValuesAndEntries1.js @@ -6,10 +6,15 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}) // [never, any][] +var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & string), number | boolean][] +var entries3 = Object.entries({}) // [string, any][] +var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] + +// type below should be [string | (string & number), any] NOT [string | number, any] +var x2: { [index: string]: any } = {1: 2}; +var entries5 = Object.entries(x2); //// [useObjectValuesAndEntries1.js] @@ -18,7 +23,11 @@ for (var _i = 0, _a = Object.values(o); _i < _a.length; _i++) { var x = _a[_i]; var y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({ a: true, b: 2 }); // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}); // [never, any][] +var entries2 = Object.entries({ a: true, b: 2 }); // [('a' & string) | ('b' & string), number | boolean][] +var entries3 = Object.entries({}); // [string, any][] +var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] +// type below should be [string | (string & number), any] NOT [string | number, any] +var x2 = { 1: 2 }; +var entries5 = Object.entries(x2); diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.symbols b/tests/baselines/reference/useObjectValuesAndEntries1.symbols index 521d3ae722eb3..f915c34608a18 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.symbols +++ b/tests/baselines/reference/useObjectValuesAndEntries1.symbols @@ -17,30 +17,48 @@ for (var x of Object.values(o)) { >x : Symbol(x, Decl(useObjectValuesAndEntries1.ts, 3, 8)) } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] >entries : Symbol(entries, Decl(useObjectValuesAndEntries1.ts, 7, 3)) ->Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries1.ts, 1, 3)) var entries1 = Object.entries(1); // <-- entries: [string, any][] >entries1 : Symbol(entries1, Decl(useObjectValuesAndEntries1.ts, 8, 3)) ->Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] +var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & string), number | boolean][] >entries2 : Symbol(entries2, Decl(useObjectValuesAndEntries1.ts, 9, 3)) ->Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 9, 31)) >b : Symbol(b, Decl(useObjectValuesAndEntries1.ts, 9, 39)) -var entries3 = Object.entries({}) // [never, any][] +var entries3 = Object.entries({}) // [string, any][] >entries3 : Symbol(entries3, Decl(useObjectValuesAndEntries1.ts, 10, 3)) ->Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) + +var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] +>entries4 : Symbol(entries4, Decl(useObjectValuesAndEntries1.ts, 11, 3)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) + +// type below should be [string | (string & number), any] NOT [string | number, any] +var x2: { [index: string]: any } = {1: 2}; +>x2 : Symbol(x2, Decl(useObjectValuesAndEntries1.ts, 14, 3)) +>index : Symbol(index, Decl(useObjectValuesAndEntries1.ts, 14, 11)) + +var entries5 = Object.entries(x2); +>entries5 : Symbol(entries5, Decl(useObjectValuesAndEntries1.ts, 15, 3)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>x2 : Symbol(x2, Decl(useObjectValuesAndEntries1.ts, 14, 3)) diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.types b/tests/baselines/reference/useObjectValuesAndEntries1.types index f04201450c00f..b326d56ab44a7 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.types +++ b/tests/baselines/reference/useObjectValuesAndEntries1.types @@ -21,39 +21,66 @@ for (var x of Object.values(o)) { >x : number } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] ->entries : ["a" | "b", number][] ->Object.entries(o) : ["a" | "b", number][] ->Object.entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] +>entries : [("a" & string) | ("b" & string), number][] +>Object.entries(o) : [("a" & string) | ("b" & string), number][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >o : { a: number; b: number; } var entries1 = Object.entries(1); // <-- entries: [string, any][] >entries1 : [string, any][] >Object.entries(1) : [string, any][] ->Object.entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >1 : 1 -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] ->entries2 : ["a" | "b", number | boolean][] ->Object.entries({a: true, b: 2}) : ["a" | "b", number | boolean][] ->Object.entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & string), number | boolean][] +>entries2 : [("a" & string) | ("b" & string), number | boolean][] +>Object.entries({a: true, b: 2}) : [("a" & string) | ("b" & string), number | boolean][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >{a: true, b: 2} : { a: true; b: number; } >a : boolean >true : true >b : number >2 : 2 -var entries3 = Object.entries({}) // [never, any][] ->entries3 : [never, any][] ->Object.entries({}) : [never, any][] ->Object.entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +var entries3 = Object.entries({}) // [string, any][] +>entries3 : [string, any][] +>Object.entries({}) : [string, any][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >{} : {} +var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] +>entries4 : [string, number][] +>Object.entries([1, 2, 3, 4]) : [string, number][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>[1, 2, 3, 4] : number[] +>1 : 1 +>2 : 2 +>3 : 3 +>4 : 4 + +// type below should be [string | (string & number), any] NOT [string | number, any] +var x2: { [index: string]: any } = {1: 2}; +>x2 : { [index: string]: any; } +>index : string +>{1: 2} : { 1: number; } +>2 : 2 + +var entries5 = Object.entries(x2); +>entries5 : [string | (number & string), any][] +>Object.entries(x2) : [string | (number & string), any][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>x2 : { [index: string]: any; } + diff --git a/tests/baselines/reference/useObjectValuesAndEntries4.symbols b/tests/baselines/reference/useObjectValuesAndEntries4.symbols index 5edf23790cd92..479dc842bc301 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries4.symbols +++ b/tests/baselines/reference/useObjectValuesAndEntries4.symbols @@ -19,8 +19,8 @@ for (var x of Object.values(o)) { var entries = Object.entries(o); >entries : Symbol(entries, Decl(useObjectValuesAndEntries4.ts, 7, 3)) ->Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) ->entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries4.ts, 1, 3)) diff --git a/tests/baselines/reference/useObjectValuesAndEntries4.types b/tests/baselines/reference/useObjectValuesAndEntries4.types index d68193993e2b6..a1f70681033b3 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries4.types +++ b/tests/baselines/reference/useObjectValuesAndEntries4.types @@ -22,10 +22,10 @@ for (var x of Object.values(o)) { } var entries = Object.entries(o); ->entries : ["a" | "b", number][] ->Object.entries(o) : ["a" | "b", number][] ->Object.entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +>entries : [("a" & string) | ("b" & string), number][] +>Object.entries(o) : [("a" & string) | ("b" & string), number][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } >o : { a: number; b: number; } diff --git a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts index 60099bb1c0f6d..683747b02c54c 100644 --- a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts +++ b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts @@ -7,7 +7,12 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][] -var entries3 = Object.entries({}) // [never, any][] +var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & string), number | boolean][] +var entries3 = Object.entries({}) // [string, any][] +var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] + +// type below should be [string | (string & number), any] NOT [string | number, any] +var x2: { [index: string]: any } = {1: 2}; +var entries5 = Object.entries(x2); From cda0c4ab54aa53a90d9d5ee3245eef841b6d7c5f Mon Sep 17 00:00:00 2001 From: Ethan Resnick Date: Mon, 14 Nov 2016 20:52:31 -0500 Subject: [PATCH 2/3] Object.keys: more precise types Applying the same logic used on Object.entries in the prior commit and in #12207 --- src/lib/es5.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 2c457a432c6b8..1252335ea2d5b 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -210,6 +210,8 @@ interface ObjectConstructor { * Returns the names of the enumerable properties and methods of an object. * @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. */ + keys(o: Array): string[]; + keys(o: T): (keyof T & string)[]; keys(o: any): string[]; } From 29105a68f5ab3a818e9ecd794b090a64524c121f Mon Sep 17 00:00:00 2001 From: Ethan Resnick Date: Sun, 27 Nov 2016 00:43:06 -0800 Subject: [PATCH 3/3] Object.keys/entries: remove keyof & string intersections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that keyof T only returns string or string subtypes (#12425), there’s no need to do keyof T & string. --- src/lib/es2017.object.d.ts | 2 +- src/lib/es5.d.ts | 2 +- .../reference/useObjectValuesAndEntries1.js | 18 +++---- .../useObjectValuesAndEntries1.symbols | 17 +++---- .../useObjectValuesAndEntries1.types | 49 +++++++++---------- .../useObjectValuesAndEntries4.types | 8 +-- .../es2017/useObjectValuesAndEntries1.ts | 9 ++-- 7 files changed, 50 insertions(+), 55 deletions(-) diff --git a/src/lib/es2017.object.d.ts b/src/lib/es2017.object.d.ts index 1bae8513b4ed2..4fdbe1cd175c2 100644 --- a/src/lib/es2017.object.d.ts +++ b/src/lib/es2017.object.d.ts @@ -10,6 +10,6 @@ interface ObjectConstructor { * @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. */ entries(o: Array): [string, T][]; - entries(o: T): [keyof T & string, T[K]][]; + entries(o: T): [keyof T, T[K]][]; entries(o: any): [string, any][]; } diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 19b937ff160fa..023af251164fb 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -223,7 +223,7 @@ interface ObjectConstructor { * @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. */ keys(o: Array): string[]; - keys(o: T): (keyof T & string)[]; + keys(o: T): (keyof T)[]; keys(o: any): string[]; } diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.js b/tests/baselines/reference/useObjectValuesAndEntries1.js index d6d538e239464..d43723a3c8847 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.js +++ b/tests/baselines/reference/useObjectValuesAndEntries1.js @@ -6,15 +6,14 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] +var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & string), number | boolean][] -var entries3 = Object.entries({}) // [string, any][] +var entries2 = Object.entries({a: true, b: 2}) // [('a' | 'b'), number | boolean][] +var entries3 = Object.entries({}) // [never, any][] var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] -// type below should be [string | (string & number), any] NOT [string | number, any] var x2: { [index: string]: any } = {1: 2}; -var entries5 = Object.entries(x2); +var entries5 = Object.entries(x2); // [string, any][] //// [useObjectValuesAndEntries1.js] @@ -23,11 +22,10 @@ for (var _i = 0, _a = Object.values(o); _i < _a.length; _i++) { var x = _a[_i]; var y = x; } -var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] +var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({ a: true, b: 2 }); // [('a' & string) | ('b' & string), number | boolean][] -var entries3 = Object.entries({}); // [string, any][] +var entries2 = Object.entries({ a: true, b: 2 }); // [('a' | 'b'), number | boolean][] +var entries3 = Object.entries({}); // [never, any][] var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] -// type below should be [string | (string & number), any] NOT [string | number, any] var x2 = { 1: 2 }; -var entries5 = Object.entries(x2); +var entries5 = Object.entries(x2); // [string, any][] diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.symbols b/tests/baselines/reference/useObjectValuesAndEntries1.symbols index f915c34608a18..fc6883d0b5358 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.symbols +++ b/tests/baselines/reference/useObjectValuesAndEntries1.symbols @@ -17,7 +17,7 @@ for (var x of Object.values(o)) { >x : Symbol(x, Decl(useObjectValuesAndEntries1.ts, 3, 8)) } -var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] +var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] >entries : Symbol(entries, Decl(useObjectValuesAndEntries1.ts, 7, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) @@ -30,7 +30,7 @@ var entries1 = Object.entries(1); // <-- entries: [string, any][] >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) -var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & string), number | boolean][] +var entries2 = Object.entries({a: true, b: 2}) // [('a' | 'b'), number | boolean][] >entries2 : Symbol(entries2, Decl(useObjectValuesAndEntries1.ts, 9, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) @@ -38,7 +38,7 @@ var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & strin >a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 9, 31)) >b : Symbol(b, Decl(useObjectValuesAndEntries1.ts, 9, 39)) -var entries3 = Object.entries({}) // [string, any][] +var entries3 = Object.entries({}) // [never, any][] >entries3 : Symbol(entries3, Decl(useObjectValuesAndEntries1.ts, 10, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) @@ -50,15 +50,14 @@ var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) -// type below should be [string | (string & number), any] NOT [string | number, any] var x2: { [index: string]: any } = {1: 2}; ->x2 : Symbol(x2, Decl(useObjectValuesAndEntries1.ts, 14, 3)) ->index : Symbol(index, Decl(useObjectValuesAndEntries1.ts, 14, 11)) +>x2 : Symbol(x2, Decl(useObjectValuesAndEntries1.ts, 13, 3)) +>index : Symbol(index, Decl(useObjectValuesAndEntries1.ts, 13, 11)) -var entries5 = Object.entries(x2); ->entries5 : Symbol(entries5, Decl(useObjectValuesAndEntries1.ts, 15, 3)) +var entries5 = Object.entries(x2); // [string, any][] +>entries5 : Symbol(entries5, Decl(useObjectValuesAndEntries1.ts, 14, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) ->x2 : Symbol(x2, Decl(useObjectValuesAndEntries1.ts, 14, 3)) +>x2 : Symbol(x2, Decl(useObjectValuesAndEntries1.ts, 13, 3)) diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.types b/tests/baselines/reference/useObjectValuesAndEntries1.types index b326d56ab44a7..019acece7431d 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.types +++ b/tests/baselines/reference/useObjectValuesAndEntries1.types @@ -21,66 +21,65 @@ for (var x of Object.values(o)) { >x : number } -var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] ->entries : [("a" & string) | ("b" & string), number][] ->Object.entries(o) : [("a" & string) | ("b" & string), number][] ->Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] +>entries : ["a" | "b", number][] +>Object.entries(o) : ["a" | "b", number][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >o : { a: number; b: number; } var entries1 = Object.entries(1); // <-- entries: [string, any][] >entries1 : [string, any][] >Object.entries(1) : [string, any][] ->Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >1 : 1 -var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & string), number | boolean][] ->entries2 : [("a" & string) | ("b" & string), number | boolean][] ->Object.entries({a: true, b: 2}) : [("a" & string) | ("b" & string), number | boolean][] ->Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +var entries2 = Object.entries({a: true, b: 2}) // [('a' | 'b'), number | boolean][] +>entries2 : ["a" | "b", number | boolean][] +>Object.entries({a: true, b: 2}) : ["a" | "b", number | boolean][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >{a: true, b: 2} : { a: true; b: number; } >a : boolean >true : true >b : number >2 : 2 -var entries3 = Object.entries({}) // [string, any][] ->entries3 : [string, any][] ->Object.entries({}) : [string, any][] ->Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +var entries3 = Object.entries({}) // [never, any][] +>entries3 : [never, any][] +>Object.entries({}) : [never, any][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >{} : {} var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] >entries4 : [string, number][] >Object.entries([1, 2, 3, 4]) : [string, number][] ->Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >[1, 2, 3, 4] : number[] >1 : 1 >2 : 2 >3 : 3 >4 : 4 -// type below should be [string | (string & number), any] NOT [string | number, any] var x2: { [index: string]: any } = {1: 2}; >x2 : { [index: string]: any; } >index : string >{1: 2} : { 1: number; } >2 : 2 -var entries5 = Object.entries(x2); ->entries5 : [string | (number & string), any][] ->Object.entries(x2) : [string | (number & string), any][] ->Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +var entries5 = Object.entries(x2); // [string, any][] +>entries5 : [string, any][] +>Object.entries(x2) : [string, any][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >x2 : { [index: string]: any; } diff --git a/tests/baselines/reference/useObjectValuesAndEntries4.types b/tests/baselines/reference/useObjectValuesAndEntries4.types index a1f70681033b3..6498ca0b48931 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries4.types +++ b/tests/baselines/reference/useObjectValuesAndEntries4.types @@ -22,10 +22,10 @@ for (var x of Object.values(o)) { } var entries = Object.entries(o); ->entries : [("a" & string) | ("b" & string), number][] ->Object.entries(o) : [("a" & string) | ("b" & string), number][] ->Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>entries : ["a" | "b", number][] +>Object.entries(o) : ["a" | "b", number][] +>Object.entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: T[]): [string, T][]; (o: T): [keyof T & string, T[K]][]; (o: any): [string, any][]; } +>entries : { (o: T[]): [string, T][]; (o: T): [keyof T, T[K]][]; (o: any): [string, any][]; } >o : { a: number; b: number; } diff --git a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts index 683747b02c54c..7a40821e5c946 100644 --- a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts +++ b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts @@ -7,12 +7,11 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); // <-- entries: [('a' & string) | ('b' & string), number][] +var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][] var entries1 = Object.entries(1); // <-- entries: [string, any][] -var entries2 = Object.entries({a: true, b: 2}) // [('a' & string) | ('b' & string), number | boolean][] -var entries3 = Object.entries({}) // [string, any][] +var entries2 = Object.entries({a: true, b: 2}) // [('a' | 'b'), number | boolean][] +var entries3 = Object.entries({}) // [never, any][] var entries4 = Object.entries([1, 2, 3, 4]); // [string, number][] -// type below should be [string | (string & number), any] NOT [string | number, any] var x2: { [index: string]: any } = {1: 2}; -var entries5 = Object.entries(x2); +var entries5 = Object.entries(x2); // [string, any][]