From 5e6b1271adbde12af50572205398bfeb21427050 Mon Sep 17 00:00:00 2001 From: Renegade334 Date: Thu, 16 Oct 2025 17:21:26 +0100 Subject: [PATCH] add proposal-upsert methods to lib.esnext.collection --- src/compiler/utilities.ts | 8 + src/lib/esnext.collection.d.ts | 30 ++ .../reference/acceptSymbolAsWeakType.symbols | 2 +- ...singDeclarationsWithIteratorObject.symbols | 2 +- ...strictbuiltiniteratorreturn=false).symbols | 2 +- ...(strictbuiltiniteratorreturn=true).symbols | 2 +- .../esNextWeakRefs_IterableWeakMap.js | 32 ++ .../esNextWeakRefs_IterableWeakMap.symbols | 145 +++++--- .../esNextWeakRefs_IterableWeakMap.types | 122 +++++++ ...Next(strictbuiltiniteratorreturn=false).js | 4 + ...strictbuiltiniteratorreturn=false).symbols | 41 ++- ...t(strictbuiltiniteratorreturn=false).types | 30 ++ ...rictbuiltiniteratorreturn=true).errors.txt | 4 +- ...TNext(strictbuiltiniteratorreturn=true).js | 4 + ...(strictbuiltiniteratorreturn=true).symbols | 41 ++- ...xt(strictbuiltiniteratorreturn=true).types | 30 ++ tests/baselines/reference/mapGroupBy.symbols | 8 +- .../baselines/reference/mapUpsert.errors.txt | 83 +++++ tests/baselines/reference/mapUpsert.js | 58 ++++ tests/baselines/reference/mapUpsert.symbols | 116 +++++++ tests/baselines/reference/mapUpsert.types | 312 ++++++++++++++++++ .../narrowingPastLastAssignment.symbols | 4 +- ...thesizedJSDocCastAtReturnStatement.symbols | 2 +- ...turnConditionalExpressionJSDocCast.symbols | 2 +- tests/baselines/reference/setMethods.symbols | 2 +- ...singDeclarationsWithIteratorObject.symbols | 2 +- .../esNextWeakRefs_IterableWeakMap.ts | 17 + tests/cases/compiler/iterableTReturnTNext.ts | 2 + tests/cases/compiler/mapUpsert.ts | 31 ++ 29 files changed, 1061 insertions(+), 77 deletions(-) create mode 100644 tests/baselines/reference/mapUpsert.errors.txt create mode 100644 tests/baselines/reference/mapUpsert.js create mode 100644 tests/baselines/reference/mapUpsert.symbols create mode 100644 tests/baselines/reference/mapUpsert.types create mode 100644 tests/cases/compiler/mapUpsert.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7f40d470abd17..f4754c57d79f2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1581,6 +1581,10 @@ export const getScriptTargetFeatures: () => ScriptTargetFeatures = /* @__PURE__ "keys", "values", ], + esnext: [ + "getOrInsert", + "getOrInsertComputed", + ], })), MapConstructor: new Map(Object.entries({ es2024: [ @@ -1635,6 +1639,10 @@ export const getScriptTargetFeatures: () => ScriptTargetFeatures = /* @__PURE__ "keys", "values", ], + esnext: [ + "getOrInsert", + "getOrInsertComputed", + ], })), WeakSet: new Map(Object.entries({ es2015: [ diff --git a/src/lib/esnext.collection.d.ts b/src/lib/esnext.collection.d.ts index 712e8d34277da..5876479766029 100644 --- a/src/lib/esnext.collection.d.ts +++ b/src/lib/esnext.collection.d.ts @@ -1,5 +1,35 @@ /// +interface Map { + /** + * Returns a specified element from the Map object. + * If no element is associated with the specified key, a new element with the value `defaultValue` will be inserted into the Map and returned. + * @returns The element associated with the specified key, which will be `defaultValue` if no element previously existed. + */ + getOrInsert(key: K, defaultValue: V): V; + /** + * Returns a specified element from the Map object. + * If no element is associated with the specified key, the result of passing the specified key to the `callback` function will be inserted into the Map and returned. + * @returns The element associated with the specific key, which will be the newly computed value if no element previously existed. + */ + getOrInsertComputed(key: K, callback: (key: K) => V): V; +} + +interface WeakMap { + /** + * Returns a specified element from the WeakMap object. + * If no element is associated with the specified key, a new element with the value `defaultValue` will be inserted into the WeakMap and returned. + * @returns The element associated with the specified key, which will be `defaultValue` if no element previously existed. + */ + getOrInsert(key: K, defaultValue: V): V; + /** + * Returns a specified element from the WeakMap object. + * If no element is associated with the specified key, the result of passing the specified key to the `callback` function will be inserted into the WeakMap and returned. + * @returns The element associated with the specific key, which will be the newly computed value if no element previously existed. + */ + getOrInsertComputed(key: K, callback: (key: K) => V): V; +} + interface ReadonlySetLike { /** * Despite its name, returns an iterator of the values in the set-like. diff --git a/tests/baselines/reference/acceptSymbolAsWeakType.symbols b/tests/baselines/reference/acceptSymbolAsWeakType.symbols index 21ec0d78f549a..0273df7988f7a 100644 --- a/tests/baselines/reference/acceptSymbolAsWeakType.symbols +++ b/tests/baselines/reference/acceptSymbolAsWeakType.symbols @@ -30,7 +30,7 @@ ws.delete(s); const wm = new WeakMap([[s, false]]); >wm : Symbol(wm, Decl(acceptSymbolAsWeakType.ts, 7, 5)) ->WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >s : Symbol(s, Decl(acceptSymbolAsWeakType.ts, 0, 5)) wm.set(s, true); diff --git a/tests/baselines/reference/awaitUsingDeclarationsWithIteratorObject.symbols b/tests/baselines/reference/awaitUsingDeclarationsWithIteratorObject.symbols index 11f28871b6eab..22b99fe6e82ac 100644 --- a/tests/baselines/reference/awaitUsingDeclarationsWithIteratorObject.symbols +++ b/tests/baselines/reference/awaitUsingDeclarationsWithIteratorObject.symbols @@ -55,7 +55,7 @@ async function f() { await using it5 = new Map().entries(); >it5 : Symbol(it5, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 15, 15)) >new Map().entries : Symbol(Map.entries, Decl(lib.es2015.iterable.d.ts, --, --)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >entries : Symbol(Map.entries, Decl(lib.es2015.iterable.d.ts, --, --)) await using it6 = new Set().keys(); diff --git a/tests/baselines/reference/builtinIteratorReturn(strictbuiltiniteratorreturn=false).symbols b/tests/baselines/reference/builtinIteratorReturn(strictbuiltiniteratorreturn=false).symbols index 121fa7517084d..00e0502508df1 100644 --- a/tests/baselines/reference/builtinIteratorReturn(strictbuiltiniteratorreturn=false).symbols +++ b/tests/baselines/reference/builtinIteratorReturn(strictbuiltiniteratorreturn=false).symbols @@ -6,7 +6,7 @@ declare const array: number[]; declare const map: Map; >map : Symbol(map, Decl(builtinIteratorReturn.ts, 1, 13)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) declare const set: Set; >set : Symbol(set, Decl(builtinIteratorReturn.ts, 2, 13)) diff --git a/tests/baselines/reference/builtinIteratorReturn(strictbuiltiniteratorreturn=true).symbols b/tests/baselines/reference/builtinIteratorReturn(strictbuiltiniteratorreturn=true).symbols index 121fa7517084d..00e0502508df1 100644 --- a/tests/baselines/reference/builtinIteratorReturn(strictbuiltiniteratorreturn=true).symbols +++ b/tests/baselines/reference/builtinIteratorReturn(strictbuiltiniteratorreturn=true).symbols @@ -6,7 +6,7 @@ declare const array: number[]; declare const map: Map; >map : Symbol(map, Decl(builtinIteratorReturn.ts, 1, 13)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) declare const set: Set; >set : Symbol(set, Decl(builtinIteratorReturn.ts, 2, 13)) diff --git a/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.js b/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.js index 4938a2ef8bd6b..9cdc2b187ddc5 100644 --- a/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.js +++ b/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.js @@ -50,6 +50,23 @@ export class IterableWeakMap implements WeakMap { return this.#weakMap.get(key)?.value; } + getOrInsert(key: K, defaultValue: V): V { + if (!this.has(key)) { + this.set(key, defaultValue); + return defaultValue; + } + return this.get(key)!; + } + + getOrInsertComputed(key: K, callback: (key: K) => V): V { + if (!this.has(key)) { + const value = callback(key); + this.set(key, value); + return value; + } + return this.get(key)!; + } + delete(key: K): boolean { const entry = this.#weakMap.get(key); if (entry === undefined) { @@ -144,6 +161,21 @@ export class IterableWeakMap { get(key) { return this.#weakMap.get(key)?.value; } + getOrInsert(key, defaultValue) { + if (!this.has(key)) { + this.set(key, defaultValue); + return defaultValue; + } + return this.get(key); + } + getOrInsertComputed(key, callback) { + if (!this.has(key)) { + const value = callback(key); + this.set(key, value); + return value; + } + return this.get(key); + } delete(key) { const entry = this.#weakMap.get(key); if (entry === undefined) { diff --git a/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols b/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols index 22f9533da2564..c776bd7d5d88e 100644 --- a/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols +++ b/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.symbols @@ -30,7 +30,7 @@ export class IterableWeakMap implements WeakMap { >IterableWeakMap : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) >K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29)) >V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46)) ->WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29)) >V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46)) @@ -42,7 +42,7 @@ export class IterableWeakMap implements WeakMap { #weakMap = new WeakMap; value: V }>(); >#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61)) ->WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29)) >ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 31)) >WeakRef : Symbol(WeakRef, Decl(lib.es2021.weakref.d.ts, --, --), Decl(lib.es2021.weakref.d.ts, --, --)) @@ -183,116 +183,185 @@ export class IterableWeakMap implements WeakMap { >value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 57)) } + getOrInsert(key: K, defaultValue: V): V { +>getOrInsert : Symbol(IterableWeakMap.getOrInsert, Decl(esNextWeakRefs_IterableWeakMap.ts, 47, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 16)) +>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29)) +>defaultValue : Symbol(defaultValue, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 23)) +>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46)) +>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46)) + + if (!this.has(key)) { +>this.has : Symbol(IterableWeakMap.has, Decl(esNextWeakRefs_IterableWeakMap.ts, 39, 5)) +>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) +>has : Symbol(IterableWeakMap.has, Decl(esNextWeakRefs_IterableWeakMap.ts, 39, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 16)) + + this.set(key, defaultValue); +>this.set : Symbol(IterableWeakMap.set, Decl(esNextWeakRefs_IterableWeakMap.ts, 22, 5)) +>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) +>set : Symbol(IterableWeakMap.set, Decl(esNextWeakRefs_IterableWeakMap.ts, 22, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 16)) +>defaultValue : Symbol(defaultValue, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 23)) + + return defaultValue; +>defaultValue : Symbol(defaultValue, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 23)) + } + return this.get(key)!; +>this.get : Symbol(IterableWeakMap.get, Decl(esNextWeakRefs_IterableWeakMap.ts, 43, 5)) +>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) +>get : Symbol(IterableWeakMap.get, Decl(esNextWeakRefs_IterableWeakMap.ts, 43, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 16)) + } + + getOrInsertComputed(key: K, callback: (key: K) => V): V { +>getOrInsertComputed : Symbol(IterableWeakMap.getOrInsertComputed, Decl(esNextWeakRefs_IterableWeakMap.ts, 55, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 57, 24)) +>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29)) +>callback : Symbol(callback, Decl(esNextWeakRefs_IterableWeakMap.ts, 57, 31)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 57, 43)) +>K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29)) +>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46)) +>V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46)) + + if (!this.has(key)) { +>this.has : Symbol(IterableWeakMap.has, Decl(esNextWeakRefs_IterableWeakMap.ts, 39, 5)) +>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) +>has : Symbol(IterableWeakMap.has, Decl(esNextWeakRefs_IterableWeakMap.ts, 39, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 57, 24)) + + const value = callback(key); +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 59, 17)) +>callback : Symbol(callback, Decl(esNextWeakRefs_IterableWeakMap.ts, 57, 31)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 57, 24)) + + this.set(key, value); +>this.set : Symbol(IterableWeakMap.set, Decl(esNextWeakRefs_IterableWeakMap.ts, 22, 5)) +>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) +>set : Symbol(IterableWeakMap.set, Decl(esNextWeakRefs_IterableWeakMap.ts, 22, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 57, 24)) +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 59, 17)) + + return value; +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 59, 17)) + } + return this.get(key)!; +>this.get : Symbol(IterableWeakMap.get, Decl(esNextWeakRefs_IterableWeakMap.ts, 43, 5)) +>this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) +>get : Symbol(IterableWeakMap.get, Decl(esNextWeakRefs_IterableWeakMap.ts, 43, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 57, 24)) + } + delete(key: K): boolean { ->delete : Symbol(IterableWeakMap.delete, Decl(esNextWeakRefs_IterableWeakMap.ts, 47, 5)) ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 11)) +>delete : Symbol(IterableWeakMap.delete, Decl(esNextWeakRefs_IterableWeakMap.ts, 64, 5)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 66, 11)) >K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29)) const entry = this.#weakMap.get(key); ->entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 50, 13)) +>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 67, 13)) >this.#weakMap.get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --)) >this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61)) >this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) >get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --)) ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 11)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 66, 11)) if (entry === undefined) { ->entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 50, 13)) +>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 67, 13)) >undefined : Symbol(undefined) return false; } const { ref } = entry; ->ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 55, 15)) ->entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 50, 13)) +>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 72, 15)) +>entry : Symbol(entry, Decl(esNextWeakRefs_IterableWeakMap.ts, 67, 13)) this.#weakMap.delete(key); >this.#weakMap.delete : Symbol(WeakMap.delete, Decl(lib.es2015.collection.d.ts, --, --)) >this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61)) >this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) >delete : Symbol(WeakMap.delete, Decl(lib.es2015.collection.d.ts, --, --)) ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 49, 11)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 66, 11)) this.#refSet.delete(ref); >this.#refSet.delete : Symbol(Set.delete, Decl(lib.es2015.collection.d.ts, --, --)) >this.#refSet : Symbol(IterableWeakMap.#refSet, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 72)) >this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) >delete : Symbol(Set.delete, Decl(lib.es2015.collection.d.ts, --, --)) ->ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 55, 15)) +>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 72, 15)) this.#finalizationGroup.unregister(ref); >this.#finalizationGroup.unregister : Symbol(FinalizationRegistry.unregister, Decl(lib.es2021.weakref.d.ts, --, --)) >this.#finalizationGroup : Symbol(IterableWeakMap.#finalizationGroup, Decl(esNextWeakRefs_IterableWeakMap.ts, 13, 36)) >this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) >unregister : Symbol(FinalizationRegistry.unregister, Decl(lib.es2021.weakref.d.ts, --, --)) ->ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 55, 15)) +>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 72, 15)) return true; } declare [Symbol.iterator]: this["entries"]; ->[Symbol.iterator] : Symbol(IterableWeakMap[Symbol.iterator], Decl(esNextWeakRefs_IterableWeakMap.ts, 60, 5)) +>[Symbol.iterator] : Symbol(IterableWeakMap[Symbol.iterator], Decl(esNextWeakRefs_IterableWeakMap.ts, 77, 5)) >Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) *entries(): Generator<[key: K, value: V], void> { ->entries : Symbol(IterableWeakMap.entries, Decl(esNextWeakRefs_IterableWeakMap.ts, 62, 47)) +>entries : Symbol(IterableWeakMap.entries, Decl(esNextWeakRefs_IterableWeakMap.ts, 79, 47)) >Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --)) >K : Symbol(K, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 29)) >V : Symbol(V, Decl(esNextWeakRefs_IterableWeakMap.ts, 9, 46)) for (const ref of this.#refSet) { ->ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 64, 18)) +>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 81, 18)) >this.#refSet : Symbol(IterableWeakMap.#refSet, Decl(esNextWeakRefs_IterableWeakMap.ts, 12, 72)) >this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) const key = ref.deref(); ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 65, 17)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 82, 17)) >ref.deref : Symbol(WeakRef.deref, Decl(lib.es2021.weakref.d.ts, --, --)) ->ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 64, 18)) +>ref : Symbol(ref, Decl(esNextWeakRefs_IterableWeakMap.ts, 81, 18)) >deref : Symbol(WeakRef.deref, Decl(lib.es2021.weakref.d.ts, --, --)) if (key === undefined) continue; ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 65, 17)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 82, 17)) >undefined : Symbol(undefined) const { value } = this.#weakMap.get(key)!; ->value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 67, 19)) +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 84, 19)) >this.#weakMap.get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --)) >this.#weakMap : Symbol(IterableWeakMap.#weakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 10, 61)) >this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) >get : Symbol(WeakMap.get, Decl(lib.es2015.collection.d.ts, --, --)) ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 65, 17)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 82, 17)) yield [key, value]; ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 65, 17)) ->value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 67, 19)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 82, 17)) +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 84, 19)) } } *keys() { ->keys : Symbol(IterableWeakMap.keys, Decl(esNextWeakRefs_IterableWeakMap.ts, 70, 5)) +>keys : Symbol(IterableWeakMap.keys, Decl(esNextWeakRefs_IterableWeakMap.ts, 87, 5)) for (const { 0: key } of this) { ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 73, 20)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 90, 20)) >this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) yield key; ->key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 73, 20)) +>key : Symbol(key, Decl(esNextWeakRefs_IterableWeakMap.ts, 90, 20)) } } *values() { ->values : Symbol(IterableWeakMap.values, Decl(esNextWeakRefs_IterableWeakMap.ts, 76, 5)) +>values : Symbol(IterableWeakMap.values, Decl(esNextWeakRefs_IterableWeakMap.ts, 93, 5)) for (const { 1: value } of this) { ->value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 79, 20)) +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 96, 20)) >this : Symbol(IterableWeakMap, Decl(esNextWeakRefs_IterableWeakMap.ts, 6, 2)) yield value; ->value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 79, 20)) +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 96, 20)) } } } @@ -306,22 +375,22 @@ Object.defineProperties(IterableWeakMap.prototype, { >prototype : Symbol(IterableWeakMap.prototype) [Symbol.iterator]: { ->[Symbol.iterator] : Symbol([Symbol.iterator], Decl(esNextWeakRefs_IterableWeakMap.ts, 85, 52)) +>[Symbol.iterator] : Symbol([Symbol.iterator], Decl(esNextWeakRefs_IterableWeakMap.ts, 102, 52)) >Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) configurable: true, ->configurable : Symbol(configurable, Decl(esNextWeakRefs_IterableWeakMap.ts, 86, 24)) +>configurable : Symbol(configurable, Decl(esNextWeakRefs_IterableWeakMap.ts, 103, 24)) enumerable: false, ->enumerable : Symbol(enumerable, Decl(esNextWeakRefs_IterableWeakMap.ts, 87, 27)) +>enumerable : Symbol(enumerable, Decl(esNextWeakRefs_IterableWeakMap.ts, 104, 27)) writable: true, ->writable : Symbol(writable, Decl(esNextWeakRefs_IterableWeakMap.ts, 88, 26)) +>writable : Symbol(writable, Decl(esNextWeakRefs_IterableWeakMap.ts, 105, 26)) value: Object.getOwnPropertyDescriptor( ->value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 89, 23)) +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 106, 23)) >Object.getOwnPropertyDescriptor( IterableWeakMap.prototype, "entries", )!.value : Symbol(PropertyDescriptor.value, Decl(lib.es5.d.ts, --, --)) >Object.getOwnPropertyDescriptor : Symbol(ObjectConstructor.getOwnPropertyDescriptor, Decl(lib.es5.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) @@ -338,22 +407,22 @@ Object.defineProperties(IterableWeakMap.prototype, { }, [Symbol.toStringTag]: { ->[Symbol.toStringTag] : Symbol([Symbol.toStringTag], Decl(esNextWeakRefs_IterableWeakMap.ts, 94, 6)) +>[Symbol.toStringTag] : Symbol([Symbol.toStringTag], Decl(esNextWeakRefs_IterableWeakMap.ts, 111, 6)) >Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) >toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) configurable: true, ->configurable : Symbol(configurable, Decl(esNextWeakRefs_IterableWeakMap.ts, 95, 27)) +>configurable : Symbol(configurable, Decl(esNextWeakRefs_IterableWeakMap.ts, 112, 27)) enumerable: false, ->enumerable : Symbol(enumerable, Decl(esNextWeakRefs_IterableWeakMap.ts, 96, 27)) +>enumerable : Symbol(enumerable, Decl(esNextWeakRefs_IterableWeakMap.ts, 113, 27)) writable: false, ->writable : Symbol(writable, Decl(esNextWeakRefs_IterableWeakMap.ts, 97, 26)) +>writable : Symbol(writable, Decl(esNextWeakRefs_IterableWeakMap.ts, 114, 26)) value: "IterableWeakMap", ->value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 98, 24)) +>value : Symbol(value, Decl(esNextWeakRefs_IterableWeakMap.ts, 115, 24)) }, }); diff --git a/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.types b/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.types index b409385e2c46e..1365e27fa6982 100644 --- a/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.types +++ b/tests/baselines/reference/esNextWeakRefs_IterableWeakMap.types @@ -291,6 +291,128 @@ export class IterableWeakMap implements WeakMap { > : ^^^^^^^^^^^^^ } + getOrInsert(key: K, defaultValue: V): V { +>getOrInsert : (key: K, defaultValue: V) => V +> : ^ ^^ ^^ ^^ ^^^^^ +>key : K +> : ^ +>defaultValue : V +> : ^ + + if (!this.has(key)) { +>!this.has(key) : boolean +> : ^^^^^^^ +>this.has(key) : boolean +> : ^^^^^^^ +>this.has : (key: K) => boolean +> : ^ ^^ ^^^^^ +>this : this +> : ^^^^ +>has : (key: K) => boolean +> : ^ ^^ ^^^^^ +>key : K +> : ^ + + this.set(key, defaultValue); +>this.set(key, defaultValue) : this +> : ^^^^ +>this.set : (key: K, value: V) => this +> : ^ ^^ ^^ ^^ ^^^^^ +>this : this +> : ^^^^ +>set : (key: K, value: V) => this +> : ^ ^^ ^^ ^^ ^^^^^ +>key : K +> : ^ +>defaultValue : V +> : ^ + + return defaultValue; +>defaultValue : V +> : ^ + } + return this.get(key)!; +>this.get(key)! : NonNullable +> : ^^^^^^^^^^^^^^ +>this.get(key) : V | undefined +> : ^^^^^^^^^^^^^ +>this.get : (key: K) => V | undefined +> : ^ ^^ ^^^^^ +>this : this +> : ^^^^ +>get : (key: K) => V | undefined +> : ^ ^^ ^^^^^ +>key : K +> : ^ + } + + getOrInsertComputed(key: K, callback: (key: K) => V): V { +>getOrInsertComputed : (key: K, callback: (key: K) => V) => V +> : ^ ^^ ^^ ^^ ^^^^^ +>key : K +> : ^ +>callback : (key: K) => V +> : ^ ^^ ^^^^^ +>key : K +> : ^ + + if (!this.has(key)) { +>!this.has(key) : boolean +> : ^^^^^^^ +>this.has(key) : boolean +> : ^^^^^^^ +>this.has : (key: K) => boolean +> : ^ ^^ ^^^^^ +>this : this +> : ^^^^ +>has : (key: K) => boolean +> : ^ ^^ ^^^^^ +>key : K +> : ^ + + const value = callback(key); +>value : V +> : ^ +>callback(key) : V +> : ^ +>callback : (key: K) => V +> : ^ ^^ ^^^^^ +>key : K +> : ^ + + this.set(key, value); +>this.set(key, value) : this +> : ^^^^ +>this.set : (key: K, value: V) => this +> : ^ ^^ ^^ ^^ ^^^^^ +>this : this +> : ^^^^ +>set : (key: K, value: V) => this +> : ^ ^^ ^^ ^^ ^^^^^ +>key : K +> : ^ +>value : V +> : ^ + + return value; +>value : V +> : ^ + } + return this.get(key)!; +>this.get(key)! : NonNullable +> : ^^^^^^^^^^^^^^ +>this.get(key) : V | undefined +> : ^^^^^^^^^^^^^ +>this.get : (key: K) => V | undefined +> : ^ ^^ ^^^^^ +>this : this +> : ^^^^ +>get : (key: K) => V | undefined +> : ^ ^^ ^^^^^ +>key : K +> : ^ + } + delete(key: K): boolean { >delete : (key: K) => boolean > : ^ ^^ ^^^^^ diff --git a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).js b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).js index 9a58042032979..52a9513cdf7ef 100644 --- a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).js +++ b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).js @@ -35,6 +35,8 @@ class MyMap implements Map { delete(key: string): boolean { return false; } forEach(callbackfn: (value: number, key: string, map: Map) => void, thisArg?: any): void { } get(key: string): number | undefined { return undefined; } + getOrInsert(key: string, defaultValue: number): number { return Number.NaN; } + getOrInsertComputed(key: string, callback: (key: string) => number): number { return Number.NaN; } has(key: string): boolean { return false; } set(key: string, value: number): this { return this; } entries(): MapIterator<[string, number]> { throw new Error("Method not implemented."); } @@ -67,6 +69,8 @@ class MyMap { delete(key) { return false; } forEach(callbackfn, thisArg) { } get(key) { return undefined; } + getOrInsert(key, defaultValue) { return Number.NaN; } + getOrInsertComputed(key, callback) { return Number.NaN; } has(key) { return false; } set(key, value) { return this; } entries() { throw new Error("Method not implemented."); } diff --git a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).symbols b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).symbols index 1806f8d645812..ae045ed5e7b57 100644 --- a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).symbols +++ b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).symbols @@ -3,7 +3,7 @@ === iterableTReturnTNext.ts === declare const map: Map; >map : Symbol(map, Decl(iterableTReturnTNext.ts, 0, 13)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) declare const set: Set; >set : Symbol(set, Decl(iterableTReturnTNext.ts, 1, 13)) @@ -70,7 +70,7 @@ const r3: number | undefined = set.values().next().value; // based on: https://github.com/microsoft/TypeScript/blob/15f67e0b482faf9f6a3ab9965f3c11196bf3e99b/src/harness/compilerImpl.ts#L77 class MyMap implements Map { >MyMap : Symbol(MyMap, Decl(iterableTReturnTNext.ts, 21, 57)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) declare private _keys: string[]; >_keys : Symbol(MyMap._keys, Decl(iterableTReturnTNext.ts, 24, 44)) @@ -100,7 +100,7 @@ class MyMap implements Map { >value : Symbol(value, Decl(iterableTReturnTNext.ts, 32, 25)) >key : Symbol(key, Decl(iterableTReturnTNext.ts, 32, 39)) >map : Symbol(map, Decl(iterableTReturnTNext.ts, 32, 52)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >thisArg : Symbol(thisArg, Decl(iterableTReturnTNext.ts, 32, 87)) get(key: string): number | undefined { return undefined; } @@ -108,28 +108,45 @@ class MyMap implements Map { >key : Symbol(key, Decl(iterableTReturnTNext.ts, 33, 8)) >undefined : Symbol(undefined) + getOrInsert(key: string, defaultValue: number): number { return Number.NaN; } +>getOrInsert : Symbol(MyMap.getOrInsert, Decl(iterableTReturnTNext.ts, 33, 62)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 34, 16)) +>defaultValue : Symbol(defaultValue, Decl(iterableTReturnTNext.ts, 34, 28)) +>Number.NaN : Symbol(NumberConstructor.NaN, Decl(lib.es5.d.ts, --, --)) +>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2020.number.d.ts, --, --)) +>NaN : Symbol(NumberConstructor.NaN, Decl(lib.es5.d.ts, --, --)) + + getOrInsertComputed(key: string, callback: (key: string) => number): number { return Number.NaN; } +>getOrInsertComputed : Symbol(MyMap.getOrInsertComputed, Decl(iterableTReturnTNext.ts, 34, 81)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 35, 24)) +>callback : Symbol(callback, Decl(iterableTReturnTNext.ts, 35, 36)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 35, 48)) +>Number.NaN : Symbol(NumberConstructor.NaN, Decl(lib.es5.d.ts, --, --)) +>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2020.number.d.ts, --, --)) +>NaN : Symbol(NumberConstructor.NaN, Decl(lib.es5.d.ts, --, --)) + has(key: string): boolean { return false; } ->has : Symbol(MyMap.has, Decl(iterableTReturnTNext.ts, 33, 62)) ->key : Symbol(key, Decl(iterableTReturnTNext.ts, 34, 8)) +>has : Symbol(MyMap.has, Decl(iterableTReturnTNext.ts, 35, 102)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 36, 8)) set(key: string, value: number): this { return this; } ->set : Symbol(MyMap.set, Decl(iterableTReturnTNext.ts, 34, 47)) ->key : Symbol(key, Decl(iterableTReturnTNext.ts, 35, 8)) ->value : Symbol(value, Decl(iterableTReturnTNext.ts, 35, 20)) +>set : Symbol(MyMap.set, Decl(iterableTReturnTNext.ts, 36, 47)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 37, 8)) +>value : Symbol(value, Decl(iterableTReturnTNext.ts, 37, 20)) >this : Symbol(MyMap, Decl(iterableTReturnTNext.ts, 21, 57)) entries(): MapIterator<[string, number]> { throw new Error("Method not implemented."); } ->entries : Symbol(MyMap.entries, Decl(iterableTReturnTNext.ts, 35, 58)) +>entries : Symbol(MyMap.entries, Decl(iterableTReturnTNext.ts, 37, 58)) >MapIterator : Symbol(MapIterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) keys(): MapIterator { throw new Error("Method not implemented."); } ->keys : Symbol(MyMap.keys, Decl(iterableTReturnTNext.ts, 36, 92)) +>keys : Symbol(MyMap.keys, Decl(iterableTReturnTNext.ts, 38, 92)) >MapIterator : Symbol(MapIterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) [Symbol.iterator](): MapIterator<[string, number]> { throw new Error("Method not implemented."); } ->[Symbol.iterator] : Symbol(MyMap[Symbol.iterator], Decl(iterableTReturnTNext.ts, 37, 79)) +>[Symbol.iterator] : Symbol(MyMap[Symbol.iterator], Decl(iterableTReturnTNext.ts, 39, 79)) >Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) @@ -138,7 +155,7 @@ class MyMap implements Map { // error when strictBuiltinIteratorReturn is true because values() has implicit `void` return, which isn't assignable to `undefined` * values() { ->values : Symbol(MyMap.values, Decl(iterableTReturnTNext.ts, 38, 102)) +>values : Symbol(MyMap.values, Decl(iterableTReturnTNext.ts, 40, 102)) yield* this._values; >this._values : Symbol(MyMap._values, Decl(iterableTReturnTNext.ts, 25, 36)) diff --git a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).types b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).types index 881e9e6a2af25..3644b2a816914 100644 --- a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).types +++ b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=false).types @@ -175,6 +175,36 @@ class MyMap implements Map { >undefined : undefined > : ^^^^^^^^^ + getOrInsert(key: string, defaultValue: number): number { return Number.NaN; } +>getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^ ^^ ^^ ^^^^^ +>key : string +> : ^^^^^^ +>defaultValue : number +> : ^^^^^^ +>Number.NaN : number +> : ^^^^^^ +>Number : NumberConstructor +> : ^^^^^^^^^^^^^^^^^ +>NaN : number +> : ^^^^^^ + + getOrInsertComputed(key: string, callback: (key: string) => number): number { return Number.NaN; } +>getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^ ^^ ^^ ^^^^^ +>key : string +> : ^^^^^^ +>callback : (key: string) => number +> : ^ ^^ ^^^^^ +>key : string +> : ^^^^^^ +>Number.NaN : number +> : ^^^^^^ +>Number : NumberConstructor +> : ^^^^^^^^^^^^^^^^^ +>NaN : number +> : ^^^^^^ + has(key: string): boolean { return false; } >has : (key: string) => boolean > : ^ ^^ ^^^^^ diff --git a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).errors.txt b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).errors.txt index 00a1ae1a8d330..30a220e1a994f 100644 --- a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).errors.txt +++ b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).errors.txt @@ -4,7 +4,7 @@ iterableTReturnTNext.ts(14,7): error TS2322: Type 'IteratorResult' is not assignable to type 'Next'. Types of property 'value' are incompatible. Type 'undefined' is not assignable to type 'number'. -iterableTReturnTNext.ts(42,7): error TS2416: Property 'values' in type 'MyMap' is not assignable to the same property in base type 'Map'. +iterableTReturnTNext.ts(44,7): error TS2416: Property 'values' in type 'MyMap' is not assignable to the same property in base type 'Map'. Type '() => Generator' is not assignable to type '() => MapIterator'. Call signature return types 'Generator' and 'MapIterator' are incompatible. The types returned by 'next(...)' are incompatible between these types. @@ -57,6 +57,8 @@ iterableTReturnTNext.ts(42,7): error TS2416: Property 'values' in type 'MyMap' i delete(key: string): boolean { return false; } forEach(callbackfn: (value: number, key: string, map: Map) => void, thisArg?: any): void { } get(key: string): number | undefined { return undefined; } + getOrInsert(key: string, defaultValue: number): number { return Number.NaN; } + getOrInsertComputed(key: string, callback: (key: string) => number): number { return Number.NaN; } has(key: string): boolean { return false; } set(key: string, value: number): this { return this; } entries(): MapIterator<[string, number]> { throw new Error("Method not implemented."); } diff --git a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).js b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).js index 9a58042032979..52a9513cdf7ef 100644 --- a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).js +++ b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).js @@ -35,6 +35,8 @@ class MyMap implements Map { delete(key: string): boolean { return false; } forEach(callbackfn: (value: number, key: string, map: Map) => void, thisArg?: any): void { } get(key: string): number | undefined { return undefined; } + getOrInsert(key: string, defaultValue: number): number { return Number.NaN; } + getOrInsertComputed(key: string, callback: (key: string) => number): number { return Number.NaN; } has(key: string): boolean { return false; } set(key: string, value: number): this { return this; } entries(): MapIterator<[string, number]> { throw new Error("Method not implemented."); } @@ -67,6 +69,8 @@ class MyMap { delete(key) { return false; } forEach(callbackfn, thisArg) { } get(key) { return undefined; } + getOrInsert(key, defaultValue) { return Number.NaN; } + getOrInsertComputed(key, callback) { return Number.NaN; } has(key) { return false; } set(key, value) { return this; } entries() { throw new Error("Method not implemented."); } diff --git a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).symbols b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).symbols index 1806f8d645812..ae045ed5e7b57 100644 --- a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).symbols +++ b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).symbols @@ -3,7 +3,7 @@ === iterableTReturnTNext.ts === declare const map: Map; >map : Symbol(map, Decl(iterableTReturnTNext.ts, 0, 13)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) declare const set: Set; >set : Symbol(set, Decl(iterableTReturnTNext.ts, 1, 13)) @@ -70,7 +70,7 @@ const r3: number | undefined = set.values().next().value; // based on: https://github.com/microsoft/TypeScript/blob/15f67e0b482faf9f6a3ab9965f3c11196bf3e99b/src/harness/compilerImpl.ts#L77 class MyMap implements Map { >MyMap : Symbol(MyMap, Decl(iterableTReturnTNext.ts, 21, 57)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) declare private _keys: string[]; >_keys : Symbol(MyMap._keys, Decl(iterableTReturnTNext.ts, 24, 44)) @@ -100,7 +100,7 @@ class MyMap implements Map { >value : Symbol(value, Decl(iterableTReturnTNext.ts, 32, 25)) >key : Symbol(key, Decl(iterableTReturnTNext.ts, 32, 39)) >map : Symbol(map, Decl(iterableTReturnTNext.ts, 32, 52)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >thisArg : Symbol(thisArg, Decl(iterableTReturnTNext.ts, 32, 87)) get(key: string): number | undefined { return undefined; } @@ -108,28 +108,45 @@ class MyMap implements Map { >key : Symbol(key, Decl(iterableTReturnTNext.ts, 33, 8)) >undefined : Symbol(undefined) + getOrInsert(key: string, defaultValue: number): number { return Number.NaN; } +>getOrInsert : Symbol(MyMap.getOrInsert, Decl(iterableTReturnTNext.ts, 33, 62)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 34, 16)) +>defaultValue : Symbol(defaultValue, Decl(iterableTReturnTNext.ts, 34, 28)) +>Number.NaN : Symbol(NumberConstructor.NaN, Decl(lib.es5.d.ts, --, --)) +>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2020.number.d.ts, --, --)) +>NaN : Symbol(NumberConstructor.NaN, Decl(lib.es5.d.ts, --, --)) + + getOrInsertComputed(key: string, callback: (key: string) => number): number { return Number.NaN; } +>getOrInsertComputed : Symbol(MyMap.getOrInsertComputed, Decl(iterableTReturnTNext.ts, 34, 81)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 35, 24)) +>callback : Symbol(callback, Decl(iterableTReturnTNext.ts, 35, 36)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 35, 48)) +>Number.NaN : Symbol(NumberConstructor.NaN, Decl(lib.es5.d.ts, --, --)) +>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2020.number.d.ts, --, --)) +>NaN : Symbol(NumberConstructor.NaN, Decl(lib.es5.d.ts, --, --)) + has(key: string): boolean { return false; } ->has : Symbol(MyMap.has, Decl(iterableTReturnTNext.ts, 33, 62)) ->key : Symbol(key, Decl(iterableTReturnTNext.ts, 34, 8)) +>has : Symbol(MyMap.has, Decl(iterableTReturnTNext.ts, 35, 102)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 36, 8)) set(key: string, value: number): this { return this; } ->set : Symbol(MyMap.set, Decl(iterableTReturnTNext.ts, 34, 47)) ->key : Symbol(key, Decl(iterableTReturnTNext.ts, 35, 8)) ->value : Symbol(value, Decl(iterableTReturnTNext.ts, 35, 20)) +>set : Symbol(MyMap.set, Decl(iterableTReturnTNext.ts, 36, 47)) +>key : Symbol(key, Decl(iterableTReturnTNext.ts, 37, 8)) +>value : Symbol(value, Decl(iterableTReturnTNext.ts, 37, 20)) >this : Symbol(MyMap, Decl(iterableTReturnTNext.ts, 21, 57)) entries(): MapIterator<[string, number]> { throw new Error("Method not implemented."); } ->entries : Symbol(MyMap.entries, Decl(iterableTReturnTNext.ts, 35, 58)) +>entries : Symbol(MyMap.entries, Decl(iterableTReturnTNext.ts, 37, 58)) >MapIterator : Symbol(MapIterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) keys(): MapIterator { throw new Error("Method not implemented."); } ->keys : Symbol(MyMap.keys, Decl(iterableTReturnTNext.ts, 36, 92)) +>keys : Symbol(MyMap.keys, Decl(iterableTReturnTNext.ts, 38, 92)) >MapIterator : Symbol(MapIterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) [Symbol.iterator](): MapIterator<[string, number]> { throw new Error("Method not implemented."); } ->[Symbol.iterator] : Symbol(MyMap[Symbol.iterator], Decl(iterableTReturnTNext.ts, 37, 79)) +>[Symbol.iterator] : Symbol(MyMap[Symbol.iterator], Decl(iterableTReturnTNext.ts, 39, 79)) >Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) >Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) >iterator : Symbol(SymbolConstructor.iterator, Decl(lib.es2015.iterable.d.ts, --, --)) @@ -138,7 +155,7 @@ class MyMap implements Map { // error when strictBuiltinIteratorReturn is true because values() has implicit `void` return, which isn't assignable to `undefined` * values() { ->values : Symbol(MyMap.values, Decl(iterableTReturnTNext.ts, 38, 102)) +>values : Symbol(MyMap.values, Decl(iterableTReturnTNext.ts, 40, 102)) yield* this._values; >this._values : Symbol(MyMap._values, Decl(iterableTReturnTNext.ts, 25, 36)) diff --git a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).types b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).types index a18a9d65133f7..28a8d14c1b549 100644 --- a/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).types +++ b/tests/baselines/reference/iterableTReturnTNext(strictbuiltiniteratorreturn=true).types @@ -181,6 +181,36 @@ class MyMap implements Map { >undefined : undefined > : ^^^^^^^^^ + getOrInsert(key: string, defaultValue: number): number { return Number.NaN; } +>getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^ ^^ ^^ ^^^^^ +>key : string +> : ^^^^^^ +>defaultValue : number +> : ^^^^^^ +>Number.NaN : number +> : ^^^^^^ +>Number : NumberConstructor +> : ^^^^^^^^^^^^^^^^^ +>NaN : number +> : ^^^^^^ + + getOrInsertComputed(key: string, callback: (key: string) => number): number { return Number.NaN; } +>getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^ ^^ ^^ ^^^^^ +>key : string +> : ^^^^^^ +>callback : (key: string) => number +> : ^ ^^ ^^^^^ +>key : string +> : ^^^^^^ +>Number.NaN : number +> : ^^^^^^ +>Number : NumberConstructor +> : ^^^^^^^^^^^^^^^^^ +>NaN : number +> : ^^^^^^ + has(key: string): boolean { return false; } >has : (key: string) => boolean > : ^ ^^ ^^^^^ diff --git a/tests/baselines/reference/mapGroupBy.symbols b/tests/baselines/reference/mapGroupBy.symbols index 615fa155d8928..b2d5c06efd7c6 100644 --- a/tests/baselines/reference/mapGroupBy.symbols +++ b/tests/baselines/reference/mapGroupBy.symbols @@ -4,7 +4,7 @@ const basic = Map.groupBy([0, 2, 8], x => x < 5 ? 'small' : 'large'); >basic : Symbol(basic, Decl(mapGroupBy.ts, 0, 5)) >Map.groupBy : Symbol(MapConstructor.groupBy, Decl(lib.es2024.collection.d.ts, --, --)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >groupBy : Symbol(MapConstructor.groupBy, Decl(lib.es2024.collection.d.ts, --, --)) >x : Symbol(x, Decl(mapGroupBy.ts, 0, 36)) >x : Symbol(x, Decl(mapGroupBy.ts, 0, 36)) @@ -12,7 +12,7 @@ const basic = Map.groupBy([0, 2, 8], x => x < 5 ? 'small' : 'large'); const chars = Map.groupBy('a string', c => c); >chars : Symbol(chars, Decl(mapGroupBy.ts, 2, 5)) >Map.groupBy : Symbol(MapConstructor.groupBy, Decl(lib.es2024.collection.d.ts, --, --)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >groupBy : Symbol(MapConstructor.groupBy, Decl(lib.es2024.collection.d.ts, --, --)) >c : Symbol(c, Decl(mapGroupBy.ts, 2, 37)) >c : Symbol(c, Decl(mapGroupBy.ts, 2, 37)) @@ -31,7 +31,7 @@ const employees: Set = new Set(); const byRole = Map.groupBy(employees, x => x.role); >byRole : Symbol(byRole, Decl(mapGroupBy.ts, 6, 5)) >Map.groupBy : Symbol(MapConstructor.groupBy, Decl(lib.es2024.collection.d.ts, --, --)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >groupBy : Symbol(MapConstructor.groupBy, Decl(lib.es2024.collection.d.ts, --, --)) >employees : Symbol(employees, Decl(mapGroupBy.ts, 5, 5)) >x : Symbol(x, Decl(mapGroupBy.ts, 6, 37)) @@ -42,7 +42,7 @@ const byRole = Map.groupBy(employees, x => x.role); const byNonKey = Map.groupBy(employees, x => x); >byNonKey : Symbol(byNonKey, Decl(mapGroupBy.ts, 8, 5)) >Map.groupBy : Symbol(MapConstructor.groupBy, Decl(lib.es2024.collection.d.ts, --, --)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >groupBy : Symbol(MapConstructor.groupBy, Decl(lib.es2024.collection.d.ts, --, --)) >employees : Symbol(employees, Decl(mapGroupBy.ts, 5, 5)) >x : Symbol(x, Decl(mapGroupBy.ts, 8, 39)) diff --git a/tests/baselines/reference/mapUpsert.errors.txt b/tests/baselines/reference/mapUpsert.errors.txt new file mode 100644 index 0000000000000..7c7abaffd3521 --- /dev/null +++ b/tests/baselines/reference/mapUpsert.errors.txt @@ -0,0 +1,83 @@ +mapUpsert.ts(14,5): error TS2554: Expected 2 arguments, but got 1. +mapUpsert.ts(15,24): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +mapUpsert.ts(16,24): error TS2345: Argument of type '() => number' is not assignable to parameter of type 'number'. +mapUpsert.ts(17,5): error TS2554: Expected 2 arguments, but got 1. +mapUpsert.ts(18,32): error TS2345: Argument of type 'number' is not assignable to parameter of type '(key: string) => number'. +mapUpsert.ts(19,38): error TS2322: Type 'string' is not assignable to type 'number'. +mapUpsert.ts(20,6): error TS2554: Expected 2 arguments, but got 1. +mapUpsert.ts(21,22): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +mapUpsert.ts(22,22): error TS2345: Argument of type '() => number' is not assignable to parameter of type 'number'. +mapUpsert.ts(23,6): error TS2554: Expected 2 arguments, but got 1. +mapUpsert.ts(24,30): error TS2345: Argument of type 'number' is not assignable to parameter of type '(key: object) => number'. +mapUpsert.ts(25,36): error TS2322: Type 'string' is not assignable to type 'number'. +mapUpsert.ts(28,6): error TS2339: Property 'getOrInsert' does not exist on type 'ReadonlyMap'. +mapUpsert.ts(29,6): error TS2339: Property 'getOrInsertComputed' does not exist on type 'ReadonlyMap'. + + +==== mapUpsert.ts (14 errors) ==== + declare const map: Map; + declare const mapR: ReadonlyMap; + declare const mapW: WeakMap; + + // OK + map.getOrInsert("key", 123); + map.getOrInsertComputed("key", () => 123); + map.getOrInsertComputed("key", (key: string) => 123); + mapW.getOrInsert({}, 123); + mapW.getOrInsertComputed({}, () => 123); + mapW.getOrInsertComputed({}, (key: object) => 123); + + // Errors + map.getOrInsert("key"); + ~~~~~~~~~~~ +!!! error TS2554: Expected 2 arguments, but got 1. +!!! related TS6210 lib.esnext.collection.d.ts:--:--: An argument for 'defaultValue' was not provided. + map.getOrInsert("key", "value"); + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + map.getOrInsert("key", () => 123); + ~~~~~~~~~ +!!! error TS2345: Argument of type '() => number' is not assignable to parameter of type 'number'. +!!! related TS6212 mapUpsert.ts:16:24: Did you mean to call this expression? + map.getOrInsertComputed("key"); + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2554: Expected 2 arguments, but got 1. +!!! related TS6210 lib.esnext.collection.d.ts:--:--: An argument for 'callback' was not provided. + map.getOrInsertComputed("key", 123); + ~~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type '(key: string) => number'. + map.getOrInsertComputed("key", () => "value"); + ~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6502 lib.esnext.collection.d.ts:--:--: The expected type comes from the return type of this signature. + mapW.getOrInsert({}); + ~~~~~~~~~~~ +!!! error TS2554: Expected 2 arguments, but got 1. +!!! related TS6210 lib.esnext.collection.d.ts:--:--: An argument for 'defaultValue' was not provided. + mapW.getOrInsert({}, "value"); + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + mapW.getOrInsert({}, () => 123); + ~~~~~~~~~ +!!! error TS2345: Argument of type '() => number' is not assignable to parameter of type 'number'. +!!! related TS6212 mapUpsert.ts:22:22: Did you mean to call this expression? + mapW.getOrInsertComputed({}); + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2554: Expected 2 arguments, but got 1. +!!! related TS6210 lib.esnext.collection.d.ts:--:--: An argument for 'callback' was not provided. + mapW.getOrInsertComputed({}, 123); + ~~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type '(key: object) => number'. + mapW.getOrInsertComputed({}, () => "value"); + ~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6502 lib.esnext.collection.d.ts:--:--: The expected type comes from the return type of this signature. + + // Not present on readonly interface + mapR.getOrInsert("key", 123); + ~~~~~~~~~~~ +!!! error TS2339: Property 'getOrInsert' does not exist on type 'ReadonlyMap'. + mapR.getOrInsertComputed("key", () => 123); + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2339: Property 'getOrInsertComputed' does not exist on type 'ReadonlyMap'. + \ No newline at end of file diff --git a/tests/baselines/reference/mapUpsert.js b/tests/baselines/reference/mapUpsert.js new file mode 100644 index 0000000000000..862c607f57136 --- /dev/null +++ b/tests/baselines/reference/mapUpsert.js @@ -0,0 +1,58 @@ +//// [tests/cases/compiler/mapUpsert.ts] //// + +//// [mapUpsert.ts] +declare const map: Map; +declare const mapR: ReadonlyMap; +declare const mapW: WeakMap; + +// OK +map.getOrInsert("key", 123); +map.getOrInsertComputed("key", () => 123); +map.getOrInsertComputed("key", (key: string) => 123); +mapW.getOrInsert({}, 123); +mapW.getOrInsertComputed({}, () => 123); +mapW.getOrInsertComputed({}, (key: object) => 123); + +// Errors +map.getOrInsert("key"); +map.getOrInsert("key", "value"); +map.getOrInsert("key", () => 123); +map.getOrInsertComputed("key"); +map.getOrInsertComputed("key", 123); +map.getOrInsertComputed("key", () => "value"); +mapW.getOrInsert({}); +mapW.getOrInsert({}, "value"); +mapW.getOrInsert({}, () => 123); +mapW.getOrInsertComputed({}); +mapW.getOrInsertComputed({}, 123); +mapW.getOrInsertComputed({}, () => "value"); + +// Not present on readonly interface +mapR.getOrInsert("key", 123); +mapR.getOrInsertComputed("key", () => 123); + + +//// [mapUpsert.js] +// OK +map.getOrInsert("key", 123); +map.getOrInsertComputed("key", function () { return 123; }); +map.getOrInsertComputed("key", function (key) { return 123; }); +mapW.getOrInsert({}, 123); +mapW.getOrInsertComputed({}, function () { return 123; }); +mapW.getOrInsertComputed({}, function (key) { return 123; }); +// Errors +map.getOrInsert("key"); +map.getOrInsert("key", "value"); +map.getOrInsert("key", function () { return 123; }); +map.getOrInsertComputed("key"); +map.getOrInsertComputed("key", 123); +map.getOrInsertComputed("key", function () { return "value"; }); +mapW.getOrInsert({}); +mapW.getOrInsert({}, "value"); +mapW.getOrInsert({}, function () { return 123; }); +mapW.getOrInsertComputed({}); +mapW.getOrInsertComputed({}, 123); +mapW.getOrInsertComputed({}, function () { return "value"; }); +// Not present on readonly interface +mapR.getOrInsert("key", 123); +mapR.getOrInsertComputed("key", function () { return 123; }); diff --git a/tests/baselines/reference/mapUpsert.symbols b/tests/baselines/reference/mapUpsert.symbols new file mode 100644 index 0000000000000..59e67ea427030 --- /dev/null +++ b/tests/baselines/reference/mapUpsert.symbols @@ -0,0 +1,116 @@ +//// [tests/cases/compiler/mapUpsert.ts] //// + +=== mapUpsert.ts === +declare const map: Map; +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) + +declare const mapR: ReadonlyMap; +>mapR : Symbol(mapR, Decl(mapUpsert.ts, 1, 13)) +>ReadonlyMap : Symbol(ReadonlyMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --)) + +declare const mapW: WeakMap; +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) + +// OK +map.getOrInsert("key", 123); +>map.getOrInsert : Symbol(Map.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsert : Symbol(Map.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) + +map.getOrInsertComputed("key", () => 123); +>map.getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) + +map.getOrInsertComputed("key", (key: string) => 123); +>map.getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>key : Symbol(key, Decl(mapUpsert.ts, 7, 32)) + +mapW.getOrInsert({}, 123); +>mapW.getOrInsert : Symbol(WeakMap.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsert : Symbol(WeakMap.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) + +mapW.getOrInsertComputed({}, () => 123); +>mapW.getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) + +mapW.getOrInsertComputed({}, (key: object) => 123); +>mapW.getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>key : Symbol(key, Decl(mapUpsert.ts, 10, 30)) + +// Errors +map.getOrInsert("key"); +>map.getOrInsert : Symbol(Map.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsert : Symbol(Map.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) + +map.getOrInsert("key", "value"); +>map.getOrInsert : Symbol(Map.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsert : Symbol(Map.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) + +map.getOrInsert("key", () => 123); +>map.getOrInsert : Symbol(Map.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsert : Symbol(Map.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) + +map.getOrInsertComputed("key"); +>map.getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) + +map.getOrInsertComputed("key", 123); +>map.getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) + +map.getOrInsertComputed("key", () => "value"); +>map.getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>map : Symbol(map, Decl(mapUpsert.ts, 0, 13)) +>getOrInsertComputed : Symbol(Map.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) + +mapW.getOrInsert({}); +>mapW.getOrInsert : Symbol(WeakMap.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsert : Symbol(WeakMap.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) + +mapW.getOrInsert({}, "value"); +>mapW.getOrInsert : Symbol(WeakMap.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsert : Symbol(WeakMap.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) + +mapW.getOrInsert({}, () => 123); +>mapW.getOrInsert : Symbol(WeakMap.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsert : Symbol(WeakMap.getOrInsert, Decl(lib.esnext.collection.d.ts, --, --)) + +mapW.getOrInsertComputed({}); +>mapW.getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) + +mapW.getOrInsertComputed({}, 123); +>mapW.getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) + +mapW.getOrInsertComputed({}, () => "value"); +>mapW.getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) +>mapW : Symbol(mapW, Decl(mapUpsert.ts, 2, 13)) +>getOrInsertComputed : Symbol(WeakMap.getOrInsertComputed, Decl(lib.esnext.collection.d.ts, --, --)) + +// Not present on readonly interface +mapR.getOrInsert("key", 123); +>mapR : Symbol(mapR, Decl(mapUpsert.ts, 1, 13)) + +mapR.getOrInsertComputed("key", () => 123); +>mapR : Symbol(mapR, Decl(mapUpsert.ts, 1, 13)) + diff --git a/tests/baselines/reference/mapUpsert.types b/tests/baselines/reference/mapUpsert.types new file mode 100644 index 0000000000000..9bde33fffdd98 --- /dev/null +++ b/tests/baselines/reference/mapUpsert.types @@ -0,0 +1,312 @@ +//// [tests/cases/compiler/mapUpsert.ts] //// + +=== mapUpsert.ts === +declare const map: Map; +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ + +declare const mapR: ReadonlyMap; +>mapR : ReadonlyMap +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +declare const mapW: WeakMap; +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ + +// OK +map.getOrInsert("key", 123); +>map.getOrInsert("key", 123) : number +> : ^^^^^^ +>map.getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ +>123 : 123 +> : ^^^ + +map.getOrInsertComputed("key", () => 123); +>map.getOrInsertComputed("key", () => 123) : number +> : ^^^^^^ +>map.getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ +>() => 123 : () => number +> : ^^^^^^^^^^^^ +>123 : 123 +> : ^^^ + +map.getOrInsertComputed("key", (key: string) => 123); +>map.getOrInsertComputed("key", (key: string) => 123) : number +> : ^^^^^^ +>map.getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ +>(key: string) => 123 : (key: string) => number +> : ^ ^^ ^^^^^^^^^^^ +>key : string +> : ^^^^^^ +>123 : 123 +> : ^^^ + +mapW.getOrInsert({}, 123); +>mapW.getOrInsert({}, 123) : number +> : ^^^^^^ +>mapW.getOrInsert : (key: object, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsert : (key: object, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ +>123 : 123 +> : ^^^ + +mapW.getOrInsertComputed({}, () => 123); +>mapW.getOrInsertComputed({}, () => 123) : number +> : ^^^^^^ +>mapW.getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ +>() => 123 : () => number +> : ^^^^^^^^^^^^ +>123 : 123 +> : ^^^ + +mapW.getOrInsertComputed({}, (key: object) => 123); +>mapW.getOrInsertComputed({}, (key: object) => 123) : number +> : ^^^^^^ +>mapW.getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ +>(key: object) => 123 : (key: object) => number +> : ^ ^^ ^^^^^^^^^^^ +>key : object +> : ^^^^^^ +>123 : 123 +> : ^^^ + +// Errors +map.getOrInsert("key"); +>map.getOrInsert("key") : number +> : ^^^^^^ +>map.getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ + +map.getOrInsert("key", "value"); +>map.getOrInsert("key", "value") : number +> : ^^^^^^ +>map.getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ +>"value" : "value" +> : ^^^^^^^ + +map.getOrInsert("key", () => 123); +>map.getOrInsert("key", () => 123) : number +> : ^^^^^^ +>map.getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsert : (key: string, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ +>() => 123 : () => number +> : ^^^^^^^^^^^^ +>123 : 123 +> : ^^^ + +map.getOrInsertComputed("key"); +>map.getOrInsertComputed("key") : number +> : ^^^^^^ +>map.getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ + +map.getOrInsertComputed("key", 123); +>map.getOrInsertComputed("key", 123) : number +> : ^^^^^^ +>map.getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ +>123 : 123 +> : ^^^ + +map.getOrInsertComputed("key", () => "value"); +>map.getOrInsertComputed("key", () => "value") : number +> : ^^^^^^ +>map.getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>map : Map +> : ^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: string, callback: (key: string) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"key" : "key" +> : ^^^^^ +>() => "value" : () => string +> : ^^^^^^^^^^^^ +>"value" : "value" +> : ^^^^^^^ + +mapW.getOrInsert({}); +>mapW.getOrInsert({}) : number +> : ^^^^^^ +>mapW.getOrInsert : (key: object, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsert : (key: object, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ + +mapW.getOrInsert({}, "value"); +>mapW.getOrInsert({}, "value") : number +> : ^^^^^^ +>mapW.getOrInsert : (key: object, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsert : (key: object, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ +>"value" : "value" +> : ^^^^^^^ + +mapW.getOrInsert({}, () => 123); +>mapW.getOrInsert({}, () => 123) : number +> : ^^^^^^ +>mapW.getOrInsert : (key: object, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsert : (key: object, defaultValue: number) => number +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ +>() => 123 : () => number +> : ^^^^^^^^^^^^ +>123 : 123 +> : ^^^ + +mapW.getOrInsertComputed({}); +>mapW.getOrInsertComputed({}) : number +> : ^^^^^^ +>mapW.getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ + +mapW.getOrInsertComputed({}, 123); +>mapW.getOrInsertComputed({}, 123) : number +> : ^^^^^^ +>mapW.getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ +>123 : 123 +> : ^^^ + +mapW.getOrInsertComputed({}, () => "value"); +>mapW.getOrInsertComputed({}, () => "value") : number +> : ^^^^^^ +>mapW.getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>mapW : WeakMap +> : ^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : (key: object, callback: (key: object) => number) => number +> : ^ ^^^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{} : {} +> : ^^ +>() => "value" : () => string +> : ^^^^^^^^^^^^ +>"value" : "value" +> : ^^^^^^^ + +// Not present on readonly interface +mapR.getOrInsert("key", 123); +>mapR.getOrInsert("key", 123) : any +> : ^^^ +>mapR.getOrInsert : any +> : ^^^ +>mapR : ReadonlyMap +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsert : any +> : ^^^ +>"key" : "key" +> : ^^^^^ +>123 : 123 +> : ^^^ + +mapR.getOrInsertComputed("key", () => 123); +>mapR.getOrInsertComputed("key", () => 123) : any +> : ^^^ +>mapR.getOrInsertComputed : any +> : ^^^ +>mapR : ReadonlyMap +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>getOrInsertComputed : any +> : ^^^ +>"key" : "key" +> : ^^^^^ +>() => 123 : () => number +> : ^^^^^^^^^^^^ +>123 : 123 +> : ^^^ + diff --git a/tests/baselines/reference/narrowingPastLastAssignment.symbols b/tests/baselines/reference/narrowingPastLastAssignment.symbols index 0aa5ff567438f..ed101b9f02643 100644 --- a/tests/baselines/reference/narrowingPastLastAssignment.symbols +++ b/tests/baselines/reference/narrowingPastLastAssignment.symbols @@ -333,9 +333,9 @@ function f12() { const fooMap: Map> = new Map() >fooMap : Symbol(fooMap, Decl(narrowingPastLastAssignment.ts, 145, 9)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 4 more) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) const values = [1, 2, 3, 4, 5]; >values : Symbol(values, Decl(narrowingPastLastAssignment.ts, 146, 9)) diff --git a/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.symbols b/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.symbols index 0bc8cf09402e8..a132bfbcf5a69 100644 --- a/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.symbols +++ b/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.symbols @@ -4,7 +4,7 @@ /** @type {Map>} */ const cache = new Map() >cache : Symbol(cache, Decl(index.js, 1, 5)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) /** * @param {string} key diff --git a/tests/baselines/reference/returnConditionalExpressionJSDocCast.symbols b/tests/baselines/reference/returnConditionalExpressionJSDocCast.symbols index 1f49ce6b305cd..6a7be194f10b7 100644 --- a/tests/baselines/reference/returnConditionalExpressionJSDocCast.symbols +++ b/tests/baselines/reference/returnConditionalExpressionJSDocCast.symbols @@ -5,7 +5,7 @@ /** @type {Map} */ const sources = new Map(); >sources : Symbol(sources, Decl(file.js, 2, 5)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) /** diff --git a/tests/baselines/reference/setMethods.symbols b/tests/baselines/reference/setMethods.symbols index e2c233be0d99e..b3661faa236f3 100644 --- a/tests/baselines/reference/setMethods.symbols +++ b/tests/baselines/reference/setMethods.symbols @@ -11,7 +11,7 @@ let stringSet = new Set(["a", "b"]); let numberMap = new Map([[4, {}], [5, {}]]); >numberMap : Symbol(numberMap, Decl(setMethods.ts, 4, 3)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) let numberSetLike = { >numberSetLike : Symbol(numberSetLike, Decl(setMethods.ts, 6, 3)) diff --git a/tests/baselines/reference/usingDeclarationsWithIteratorObject.symbols b/tests/baselines/reference/usingDeclarationsWithIteratorObject.symbols index caf73d6c9baeb..755505f96ce04 100644 --- a/tests/baselines/reference/usingDeclarationsWithIteratorObject.symbols +++ b/tests/baselines/reference/usingDeclarationsWithIteratorObject.symbols @@ -55,7 +55,7 @@ function f() { using it5 = new Map().entries(); >it5 : Symbol(it5, Decl(usingDeclarationsWithIteratorObject.ts, 15, 9)) >new Map().entries : Symbol(Map.entries, Decl(lib.es2015.iterable.d.ts, --, --)) ->Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.collection.d.ts, --, --)) >entries : Symbol(Map.entries, Decl(lib.es2015.iterable.d.ts, --, --)) using it6 = new Set().keys(); diff --git a/tests/cases/compiler/esNextWeakRefs_IterableWeakMap.ts b/tests/cases/compiler/esNextWeakRefs_IterableWeakMap.ts index 220b56a3d8296..2608244487ac0 100644 --- a/tests/cases/compiler/esNextWeakRefs_IterableWeakMap.ts +++ b/tests/cases/compiler/esNextWeakRefs_IterableWeakMap.ts @@ -52,6 +52,23 @@ export class IterableWeakMap implements WeakMap { return this.#weakMap.get(key)?.value; } + getOrInsert(key: K, defaultValue: V): V { + if (!this.has(key)) { + this.set(key, defaultValue); + return defaultValue; + } + return this.get(key)!; + } + + getOrInsertComputed(key: K, callback: (key: K) => V): V { + if (!this.has(key)) { + const value = callback(key); + this.set(key, value); + return value; + } + return this.get(key)!; + } + delete(key: K): boolean { const entry = this.#weakMap.get(key); if (entry === undefined) { diff --git a/tests/cases/compiler/iterableTReturnTNext.ts b/tests/cases/compiler/iterableTReturnTNext.ts index f17276e4c6797..c863722515bd0 100644 --- a/tests/cases/compiler/iterableTReturnTNext.ts +++ b/tests/cases/compiler/iterableTReturnTNext.ts @@ -36,6 +36,8 @@ class MyMap implements Map { delete(key: string): boolean { return false; } forEach(callbackfn: (value: number, key: string, map: Map) => void, thisArg?: any): void { } get(key: string): number | undefined { return undefined; } + getOrInsert(key: string, defaultValue: number): number { return Number.NaN; } + getOrInsertComputed(key: string, callback: (key: string) => number): number { return Number.NaN; } has(key: string): boolean { return false; } set(key: string, value: number): this { return this; } entries(): MapIterator<[string, number]> { throw new Error("Method not implemented."); } diff --git a/tests/cases/compiler/mapUpsert.ts b/tests/cases/compiler/mapUpsert.ts new file mode 100644 index 0000000000000..21a2e400063a8 --- /dev/null +++ b/tests/cases/compiler/mapUpsert.ts @@ -0,0 +1,31 @@ +// @lib: esnext + +declare const map: Map; +declare const mapR: ReadonlyMap; +declare const mapW: WeakMap; + +// OK +map.getOrInsert("key", 123); +map.getOrInsertComputed("key", () => 123); +map.getOrInsertComputed("key", (key: string) => 123); +mapW.getOrInsert({}, 123); +mapW.getOrInsertComputed({}, () => 123); +mapW.getOrInsertComputed({}, (key: object) => 123); + +// Errors +map.getOrInsert("key"); +map.getOrInsert("key", "value"); +map.getOrInsert("key", () => 123); +map.getOrInsertComputed("key"); +map.getOrInsertComputed("key", 123); +map.getOrInsertComputed("key", () => "value"); +mapW.getOrInsert({}); +mapW.getOrInsert({}, "value"); +mapW.getOrInsert({}, () => 123); +mapW.getOrInsertComputed({}); +mapW.getOrInsertComputed({}, 123); +mapW.getOrInsertComputed({}, () => "value"); + +// Not present on readonly interface +mapR.getOrInsert("key", 123); +mapR.getOrInsertComputed("key", () => 123);