built-in iterators should be disposable (#59633)

This commit is contained in:
Ron Buckton
2024-08-16 11:57:04 -04:00
committed by GitHub
parent 09a8522294
commit f025a5b879
22 changed files with 951 additions and 105 deletions

View File

@@ -10,7 +10,7 @@ const sourceFileJs = vpath.combine(vfs.srcFolder, "source.js");
// Define a custom "Symbol" constructor to attach missing built-in symbols without
// modifying the global "Symbol" constructor
const FakeSymbol: SymbolConstructor = ((description?: string) => Symbol(description)) as any;
export const FakeSymbol: SymbolConstructor = ((description?: string) => Symbol(description)) as any;
(FakeSymbol as any).prototype = Symbol.prototype;
for (const key of Object.getOwnPropertyNames(Symbol)) {
Object.defineProperty(FakeSymbol, key, Object.getOwnPropertyDescriptor(Symbol, key)!);

View File

@@ -1,4 +1,6 @@
/// <reference lib="es2015.symbol" />
/// <reference lib="es2015.iterable" />
/// <reference lib="es2018.asynciterable" />
interface SymbolConstructor {
/**
@@ -165,3 +167,9 @@ interface AsyncDisposableStackConstructor {
readonly prototype: AsyncDisposableStack;
}
declare var AsyncDisposableStack: AsyncDisposableStackConstructor;
interface IteratorObject<T, TReturn, TNext> extends Disposable {
}
interface AsyncIteratorObject<T, TReturn, TNext> extends AsyncDisposable {
}

View File

@@ -1874,4 +1874,140 @@ describe("unittests:: evaluation:: awaitUsingDeclarations", () => {
"catch",
]);
});
it("deterministic collapse of Await", async () => {
const { main, output } = evaluator.evaluateTypeScript(
`
export const output: any[] = [];
let asyncId = 0;
function increment() { asyncId++; }
export async function main() {
// increment asyncId at the top of each turn of the microtask queue
let pending = Promise.resolve();
for (let i = 0; i < 10; i++) {
pending = pending.then(increment);
}
{
using sync1 = { [Symbol.dispose]() { output.push(asyncId); } }; // asyncId: 2
await using async1 = null, async2 = null;
using sync2 = { [Symbol.dispose]() { output.push(asyncId); } }; // asyncId: 1
await using async3 = null, async4 = null;
output.push(asyncId); // asyncId: 0
}
output.push(asyncId); // asyncId: Ideally, 2, but ends up being 4 due to delays imposed by 'await'
await pending; // wait for the remaining 'increment' frames to complete.
}
`,
{ target: ts.ScriptTarget.ES2018 },
);
await main();
assert.deepEqual(output, [
0,
1,
2,
// This really should be 2, but our transpile introduces an extra `await` by necessity to observe the
// result of __disposeResources. The process of adopting the result ends up taking two turns of the
// microtask queue.
4,
]);
});
it("'await using' with downlevel generators", async () => {
abstract class Iterator {
return?(): void;
[evaluator.FakeSymbol.iterator]() {
return this;
}
[evaluator.FakeSymbol.dispose]() {
this.return?.();
}
}
const { main } = evaluator.evaluateTypeScript(
`
let exited = false;
function * f() {
try {
yield;
}
finally {
exited = true;
}
}
export async function main() {
{
await using g = f();
g.next();
}
return exited;
}
`,
{
target: ts.ScriptTarget.ES5,
},
{
Iterator,
},
);
const exited = await main();
assert.isTrue(exited, "Expected 'await using' to dispose generator");
});
it("'await using' with downlevel async generators", async () => {
abstract class AsyncIterator {
return?(): PromiseLike<void>;
[evaluator.FakeSymbol.asyncIterator]() {
return this;
}
async [evaluator.FakeSymbol.asyncDispose]() {
await this.return?.();
}
}
const { main } = evaluator.evaluateTypeScript(
`
let exited = false;
async function * f() {
try {
yield;
}
finally {
exited = true;
}
}
export async function main() {
{
await using g = f();
await g.next();
}
return exited;
}
`,
{
target: ts.ScriptTarget.ES5,
},
{
AsyncIterator,
},
);
const exited = await main();
assert.isTrue(exited, "Expected 'await using' to dispose async generator");
});
});

View File

@@ -1811,49 +1811,48 @@ describe("unittests:: evaluation:: usingDeclarations", () => {
]);
});
it("deterministic collapse of Await", async () => {
const { main, output } = evaluator.evaluateTypeScript(
`
export const output: any[] = [];
let asyncId = 0;
function increment() { asyncId++; }
export async function main() {
// increment asyncId at the top of each turn of the microtask queue
let pending = Promise.resolve();
for (let i = 0; i < 10; i++) {
pending = pending.then(increment);
it("'using' with downlevel generators", () => {
abstract class Iterator {
return?(): void;
[evaluator.FakeSymbol.iterator]() {
return this;
}
{
using sync1 = { [Symbol.dispose]() { output.push(asyncId); } }; // asyncId: 2
await using async1 = null, async2 = null;
using sync2 = { [Symbol.dispose]() { output.push(asyncId); } }; // asyncId: 1
await using async3 = null, async4 = null;
output.push(asyncId); // asyncId: 0
[evaluator.FakeSymbol.dispose]() {
this.return?.();
}
output.push(asyncId); // asyncId: Ideally, 2, but ends up being 4 due to delays imposed by 'await'
await pending; // wait for the remaining 'increment' frames to complete.
}
const { main } = evaluator.evaluateTypeScript(
`
let exited = false;
function * f() {
try {
yield;
}
finally {
exited = true;
}
}
export function main() {
{
using g = f();
g.next();
}
return exited;
}
`,
{ target: ts.ScriptTarget.ES2018 },
{
target: ts.ScriptTarget.ES5,
},
{
Iterator,
},
);
await main();
assert.deepEqual(output, [
0,
1,
2,
// This really should be 2, but our transpile introduces an extra `await` by necessity to observe the
// result of __disposeResources. The process of adopting the result ends up taking two turns of the
// microtask queue.
4,
]);
const exited = main();
assert.isTrue(exited, "Expected 'using' to dispose generator");
});
});

View File

@@ -0,0 +1,19 @@
awaitUsingDeclarationsWithAsyncIteratorObject.ts(11,23): error TS2851: The initializer of an 'await using' declaration must be either an object with a '[Symbol.asyncDispose]()' or '[Symbol.dispose]()' method, or be 'null' or 'undefined'.
==== awaitUsingDeclarationsWithAsyncIteratorObject.ts (1 errors) ====
declare const ai: AsyncIterator<string, undefined>;
declare const aio: AsyncIteratorObject<string, undefined, unknown>;
declare const ag: AsyncGenerator<string, void>;
async function f() {
// should pass
await using it0 = aio;
await using it1 = ag;
// should fail
await using it2 = ai;
~~
!!! error TS2851: The initializer of an 'await using' declaration must be either an object with a '[Symbol.asyncDispose]()' or '[Symbol.dispose]()' method, or be 'null' or 'undefined'.
}

View File

@@ -0,0 +1,33 @@
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsWithAsyncIteratorObject.ts] ////
=== awaitUsingDeclarationsWithAsyncIteratorObject.ts ===
declare const ai: AsyncIterator<string, undefined>;
>ai : Symbol(ai, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 0, 13))
>AsyncIterator : Symbol(AsyncIterator, Decl(lib.es2018.asynciterable.d.ts, --, --))
declare const aio: AsyncIteratorObject<string, undefined, unknown>;
>aio : Symbol(aio, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 1, 13))
>AsyncIteratorObject : Symbol(AsyncIteratorObject, Decl(lib.es2018.asynciterable.d.ts, --, --), Decl(lib.esnext.disposable.d.ts, --, --))
declare const ag: AsyncGenerator<string, void>;
>ag : Symbol(ag, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 2, 13))
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
async function f() {
>f : Symbol(f, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 2, 47))
// should pass
await using it0 = aio;
>it0 : Symbol(it0, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 6, 15))
>aio : Symbol(aio, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 1, 13))
await using it1 = ag;
>it1 : Symbol(it1, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 7, 15))
>ag : Symbol(ag, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 2, 13))
// should fail
await using it2 = ai;
>it2 : Symbol(it2, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 10, 15))
>ai : Symbol(ai, Decl(awaitUsingDeclarationsWithAsyncIteratorObject.ts, 0, 13))
}

View File

@@ -0,0 +1,40 @@
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsWithAsyncIteratorObject.ts] ////
=== awaitUsingDeclarationsWithAsyncIteratorObject.ts ===
declare const ai: AsyncIterator<string, undefined>;
>ai : AsyncIterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
declare const aio: AsyncIteratorObject<string, undefined, unknown>;
>aio : AsyncIteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
declare const ag: AsyncGenerator<string, void>;
>ag : AsyncGenerator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
async function f() {
>f : () => Promise<void>
> : ^^^^^^^^^^^^^^^^^^^
// should pass
await using it0 = aio;
>it0 : AsyncIteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>aio : AsyncIteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
await using it1 = ag;
>it1 : AsyncGenerator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>ag : AsyncGenerator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// should fail
await using it2 = ai;
>it2 : AsyncIterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>ai : AsyncIterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

View File

@@ -0,0 +1,28 @@
awaitUsingDeclarationsWithIteratorObject.ts(20,23): error TS2851: The initializer of an 'await using' declaration must be either an object with a '[Symbol.asyncDispose]()' or '[Symbol.dispose]()' method, or be 'null' or 'undefined'.
==== awaitUsingDeclarationsWithIteratorObject.ts (1 errors) ====
declare const i: Iterator<string, undefined>;
declare const io: IteratorObject<string, undefined, unknown>;
declare const g: Generator<string, void>;
class MyIterator extends Iterator<string> {
next() { return { done: true, value: undefined }; }
}
async function f() {
// should pass
await using it0 = io;
await using it1 = g;
await using it2 = Iterator.from(i)
await using it3 = new MyIterator();
await using it4 = [].values();
await using it5 = new Map<string, string>().entries();
await using it6 = new Set<string>().keys();
// should fail
await using it7 = i;
~
!!! error TS2851: The initializer of an 'await using' declaration must be either an object with a '[Symbol.asyncDispose]()' or '[Symbol.dispose]()' method, or be 'null' or 'undefined'.
}

View File

@@ -0,0 +1,72 @@
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsWithIteratorObject.ts] ////
=== awaitUsingDeclarationsWithIteratorObject.ts ===
declare const i: Iterator<string, undefined>;
>i : Symbol(i, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 0, 13))
>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
declare const io: IteratorObject<string, undefined, unknown>;
>io : Symbol(io, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 1, 13))
>IteratorObject : Symbol(IteratorObject, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.disposable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
declare const g: Generator<string, void>;
>g : Symbol(g, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 2, 13))
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
class MyIterator extends Iterator<string> {
>MyIterator : Symbol(MyIterator, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 2, 41))
>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
next() { return { done: true, value: undefined }; }
>next : Symbol(MyIterator.next, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 4, 43))
>done : Symbol(done, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 5, 21))
>value : Symbol(value, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 5, 33))
>undefined : Symbol(undefined)
}
async function f() {
>f : Symbol(f, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 6, 1))
// should pass
await using it0 = io;
>it0 : Symbol(it0, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 10, 15))
>io : Symbol(io, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 1, 13))
await using it1 = g;
>it1 : Symbol(it1, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 11, 15))
>g : Symbol(g, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 2, 13))
await using it2 = Iterator.from(i)
>it2 : Symbol(it2, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 12, 15))
>Iterator.from : Symbol(IteratorConstructor.from, Decl(lib.esnext.iterator.d.ts, --, --))
>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
>from : Symbol(IteratorConstructor.from, Decl(lib.esnext.iterator.d.ts, --, --))
>i : Symbol(i, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 0, 13))
await using it3 = new MyIterator();
>it3 : Symbol(it3, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 13, 15))
>MyIterator : Symbol(MyIterator, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 2, 41))
await using it4 = [].values();
>it4 : Symbol(it4, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 14, 15))
>[].values : Symbol(Array.values, Decl(lib.es2015.iterable.d.ts, --, --))
>values : Symbol(Array.values, Decl(lib.es2015.iterable.d.ts, --, --))
await using it5 = new Map<string, string>().entries();
>it5 : Symbol(it5, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 15, 15))
>new Map<string, string>().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, --, --))
>entries : Symbol(Map.entries, Decl(lib.es2015.iterable.d.ts, --, --))
await using it6 = new Set<string>().keys();
>it6 : Symbol(it6, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 16, 15))
>new Set<string>().keys : Symbol(Set.keys, Decl(lib.es2015.iterable.d.ts, --, --))
>Set : Symbol(Set, 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, --, --))
>keys : Symbol(Set.keys, Decl(lib.es2015.iterable.d.ts, --, --))
// should fail
await using it7 = i;
>it7 : Symbol(it7, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 19, 15))
>i : Symbol(i, Decl(awaitUsingDeclarationsWithIteratorObject.ts, 0, 13))
}

View File

@@ -0,0 +1,123 @@
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/awaitUsingDeclarationsWithIteratorObject.ts] ////
=== awaitUsingDeclarationsWithIteratorObject.ts ===
declare const i: Iterator<string, undefined>;
>i : Iterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
declare const io: IteratorObject<string, undefined, unknown>;
>io : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
declare const g: Generator<string, void>;
>g : Generator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyIterator extends Iterator<string> {
>MyIterator : MyIterator
> : ^^^^^^^^^^
>Iterator : Iterator<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
next() { return { done: true, value: undefined }; }
>next : () => { done: boolean; value: any; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ done: true, value: undefined } : { done: boolean; value: undefined; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>done : boolean
> : ^^^^^^^
>true : true
> : ^^^^
>value : undefined
> : ^^^^^^^^^
>undefined : undefined
> : ^^^^^^^^^
}
async function f() {
>f : () => Promise<void>
> : ^^^^^^^^^^^^^^^^^^^
// should pass
await using it0 = io;
>it0 : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>io : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
await using it1 = g;
>it1 : Generator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>g : Generator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
await using it2 = Iterator.from(i)
>it2 : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Iterator.from(i) : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Iterator.from : <T>(value: Iterator<T, unknown, undefined> | Iterable<T, unknown, undefined>) => IteratorObject<T, undefined, unknown>
> : ^ ^^ ^^ ^^^^^
>Iterator : IteratorConstructor
> : ^^^^^^^^^^^^^^^^^^^
>from : <T>(value: Iterator<T, unknown, undefined> | Iterable<T, unknown, undefined>) => IteratorObject<T, undefined, unknown>
> : ^ ^^ ^^ ^^^^^
>i : Iterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
await using it3 = new MyIterator();
>it3 : MyIterator
> : ^^^^^^^^^^
>new MyIterator() : MyIterator
> : ^^^^^^^^^^
>MyIterator : typeof MyIterator
> : ^^^^^^^^^^^^^^^^^
await using it4 = [].values();
>it4 : ArrayIterator<any>
> : ^^^^^^^^^^^^^^^^^^
>[].values() : ArrayIterator<any>
> : ^^^^^^^^^^^^^^^^^^
>[].values : () => ArrayIterator<any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^
>[] : undefined[]
> : ^^^^^^^^^^^
>values : () => ArrayIterator<any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^
await using it5 = new Map<string, string>().entries();
>it5 : MapIterator<[string, string]>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>new Map<string, string>().entries() : MapIterator<[string, string]>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>new Map<string, string>().entries : () => MapIterator<[string, string]>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>new Map<string, string>() : Map<string, string>
> : ^^^^^^^^^^^^^^^^^^^
>Map : MapConstructor
> : ^^^^^^^^^^^^^^
>entries : () => MapIterator<[string, string]>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
await using it6 = new Set<string>().keys();
>it6 : SetIterator<string>
> : ^^^^^^^^^^^^^^^^^^^
>new Set<string>().keys() : SetIterator<string>
> : ^^^^^^^^^^^^^^^^^^^
>new Set<string>().keys : () => SetIterator<string>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
>new Set<string>() : Set<string>
> : ^^^^^^^^^^^
>Set : SetConstructor
> : ^^^^^^^^^^^^^^
>keys : () => SetIterator<string>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
// should fail
await using it7 = i;
>it7 : Iterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>i : Iterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

View File

@@ -184,7 +184,7 @@ const iter1 = Iterator.from(g1);
declare const iter2: IteratorObject<string>;
>iter2 : Symbol(iter2, Decl(builtinIterator.ts, 71, 13))
>IteratorObject : Symbol(IteratorObject, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
>IteratorObject : Symbol(IteratorObject, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.disposable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
const iter3 = iter2.flatMap(() => g1);
>iter3 : Symbol(iter3, Decl(builtinIterator.ts, 72, 5))

View File

@@ -110,8 +110,10 @@ function mapAsyncIterable<T, U, R = undefined>(
>next : Symbol(AsyncIterator.next, Decl(lib.es2018.asynciterable.d.ts, --, --))
},
async return(): Promise<IteratorResult<U, R>> {
async return(value: R): Promise<IteratorResult<U, R>> {
>return : Symbol(return, Decl(discriminateWithOptionalProperty2.ts, 32, 6))
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 33, 17))
>R : Symbol(R, Decl(discriminateWithOptionalProperty2.ts, 4, 31))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
>IteratorResult : Symbol(IteratorResult, Decl(lib.es2015.iterable.d.ts, --, --))
>U : Symbol(U, Decl(discriminateWithOptionalProperty2.ts, 4, 28))
@@ -122,11 +124,12 @@ function mapAsyncIterable<T, U, R = undefined>(
>iterator : Symbol(iterator, Decl(discriminateWithOptionalProperty2.ts, 8, 7))
>return : Symbol(AsyncIterator.return, Decl(lib.es2018.asynciterable.d.ts, --, --))
? mapResult(await iterator.return())
? mapResult(await iterator.return(value))
>mapResult : Symbol(mapResult, Decl(discriminateWithOptionalProperty2.ts, 8, 52))
>iterator.return : Symbol(AsyncIterator.return, Decl(lib.es2018.asynciterable.d.ts, --, --))
>iterator : Symbol(iterator, Decl(discriminateWithOptionalProperty2.ts, 8, 7))
>return : Symbol(AsyncIterator.return, Decl(lib.es2018.asynciterable.d.ts, --, --))
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 33, 17))
: { value: undefined as any, done: true };
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 36, 11))
@@ -164,35 +167,47 @@ function mapAsyncIterable<T, U, R = undefined>(
>this : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
},
async [Symbol.asyncDispose]() {
>[Symbol.asyncDispose] : Symbol([Symbol.asyncDispose], Decl(discriminateWithOptionalProperty2.ts, 46, 6))
>Symbol.asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.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, --, --))
>asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
await this.return(undefined!);
>this.return : Symbol(AsyncGenerator.return, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
>this : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
>return : Symbol(AsyncGenerator.return, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
>undefined : Symbol(undefined)
}
};
}
const items = [1, 2, 3];
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 50, 5))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 53, 5))
const iterable = {
>iterable : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 52, 5))
>iterable : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 55, 5))
[Symbol.asyncIterator]() {
>[Symbol.asyncIterator] : Symbol([Symbol.asyncIterator], Decl(discriminateWithOptionalProperty2.ts, 52, 18))
>[Symbol.asyncIterator] : Symbol([Symbol.asyncIterator], Decl(discriminateWithOptionalProperty2.ts, 55, 18))
>Symbol.asyncIterator : Symbol(SymbolConstructor.asyncIterator, Decl(lib.es2018.asynciterable.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, --, --))
>asyncIterator : Symbol(SymbolConstructor.asyncIterator, Decl(lib.es2018.asynciterable.d.ts, --, --))
return this;
>this : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 52, 16))
>this : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 55, 16))
},
next() {
>next : Symbol(next, Decl(discriminateWithOptionalProperty2.ts, 55, 4))
>next : Symbol(next, Decl(discriminateWithOptionalProperty2.ts, 58, 4))
const value = items[0];
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 57, 9))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 50, 5))
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 60, 9))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 53, 5))
items.shift();
>items.shift : Symbol(Array.shift, Decl(lib.es5.d.ts, --, --))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 50, 5))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 53, 5))
>shift : Symbol(Array.shift, Decl(lib.es5.d.ts, --, --))
return Promise.resolve({
@@ -201,23 +216,23 @@ const iterable = {
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
done: items.length === 0,
>done : Symbol(done, Decl(discriminateWithOptionalProperty2.ts, 59, 28))
>done : Symbol(done, Decl(discriminateWithOptionalProperty2.ts, 62, 28))
>items.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 50, 5))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 53, 5))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
value,
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 60, 31))
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 63, 31))
});
},
};
const doubles = mapAsyncIterable(iterable, (x) => x + x);
>doubles : Symbol(doubles, Decl(discriminateWithOptionalProperty2.ts, 66, 5))
>doubles : Symbol(doubles, Decl(discriminateWithOptionalProperty2.ts, 69, 5))
>mapAsyncIterable : Symbol(mapAsyncIterable, Decl(discriminateWithOptionalProperty2.ts, 2, 40))
>iterable : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 52, 5))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 66, 44))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 66, 44))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 66, 44))
>iterable : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 55, 5))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 69, 44))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 69, 44))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 69, 44))

View File

@@ -125,8 +125,8 @@ function mapAsyncIterable<T, U, R = undefined>(
}
return {
>{ async next() { return mapResult(await iterator.next()); }, async return(): Promise<IteratorResult<U, R>> { return typeof iterator.return === "function" ? mapResult(await iterator.return()) : { value: undefined as any, done: true }; }, async throw(error?: unknown) { if (typeof iterator.throw === "function") { return mapResult(await iterator.throw(error)); } throw error; }, [Symbol.asyncIterator]() { return this; }, } : { next(): Promise<IteratorResult<U, R>>; return(): Promise<IteratorResult<U, R>>; throw(error?: unknown): Promise<IteratorResult<U, R>>; [Symbol.asyncIterator](): AsyncGenerator<U, R, void>; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ async next() { return mapResult(await iterator.next()); }, async return(value: R): Promise<IteratorResult<U, R>> { return typeof iterator.return === "function" ? mapResult(await iterator.return(value)) : { value: undefined as any, done: true }; }, async throw(error?: unknown) { if (typeof iterator.throw === "function") { return mapResult(await iterator.throw(error)); } throw error; }, [Symbol.asyncIterator]() { return this; }, async [Symbol.asyncDispose]() { await this.return(undefined!); } } : { next(): Promise<IteratorResult<U, R>>; return(value: R): Promise<IteratorResult<U, R>>; throw(error?: unknown): Promise<IteratorResult<U, R>>; [Symbol.asyncIterator](): AsyncGenerator<U, R, void>; [Symbol.asyncDispose](): Promise<void>; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^ ^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
async next() {
>next : () => Promise<IteratorResult<U, R>>
@@ -149,13 +149,15 @@ function mapAsyncIterable<T, U, R = undefined>(
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
},
async return(): Promise<IteratorResult<U, R>> {
>return : () => Promise<IteratorResult<U, R>>
> : ^^^^^^
async return(value: R): Promise<IteratorResult<U, R>> {
>return : (value: R) => Promise<IteratorResult<U, R>>
> : ^ ^^ ^^^^^
>value : R
> : ^
return typeof iterator.return === "function"
>typeof iterator.return === "function" ? mapResult(await iterator.return()) : { value: undefined as any, done: true } : Promise<IteratorResult<U, R>> | { value: any; done: true; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
>typeof iterator.return === "function" ? mapResult(await iterator.return(value)) : { value: undefined as any, done: true } : Promise<IteratorResult<U, R>> | { value: any; done: true; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
>typeof iterator.return === "function" : boolean
> : ^^^^^^^
>typeof iterator.return : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
@@ -169,21 +171,23 @@ function mapAsyncIterable<T, U, R = undefined>(
>"function" : "function"
> : ^^^^^^^^^^
? mapResult(await iterator.return())
>mapResult(await iterator.return()) : Promise<IteratorResult<U, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
? mapResult(await iterator.return(value))
>mapResult(await iterator.return(value)) : Promise<IteratorResult<U, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>mapResult : (result: IteratorResult<T, R>) => Promise<IteratorResult<U, R>>
> : ^ ^^ ^^^^^
>await iterator.return() : IteratorResult<T, R>
> : ^^^^^^^^^^^^^^^^^^^^
>iterator.return() : Promise<IteratorResult<T, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>await iterator.return(value) : IteratorResult<T, R>
> : ^^^^^^^^^^^^^^^^^^^^
>iterator.return(value) : Promise<IteratorResult<T, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>iterator.return : (value?: R | PromiseLike<R> | undefined) => Promise<IteratorResult<T, R>>
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>iterator : AsyncIterator<T, R, undefined>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>return : (value?: R | PromiseLike<R> | undefined) => Promise<IteratorResult<T, R>>
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : R
> : ^
: { value: undefined as any, done: true };
>{ value: undefined as any, done: true } : { value: any; done: true; }
@@ -256,6 +260,32 @@ function mapAsyncIterable<T, U, R = undefined>(
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^
},
async [Symbol.asyncDispose]() {
>[Symbol.asyncDispose] : () => Promise<void>
> : ^^^^^^^^^^^^^^^^^^^
>Symbol.asyncDispose : unique symbol
> : ^^^^^^^^^^^^^
>Symbol : SymbolConstructor
> : ^^^^^^^^^^^^^^^^^
>asyncDispose : unique symbol
> : ^^^^^^^^^^^^^
await this.return(undefined!);
>await this.return(undefined!) : IteratorResult<U, R>
> : ^^^^^^^^^^^^^^^^^^^^
>this.return(undefined!) : Promise<IteratorResult<U, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>this.return : (value: R | PromiseLike<R>) => Promise<IteratorResult<U, R>>
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>this : AsyncGenerator<U, R, void>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^
>return : (value: R | PromiseLike<R>) => Promise<IteratorResult<U, R>>
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>undefined! : never
> : ^^^^^
>undefined : undefined
> : ^^^^^^^^^
}
};
}

View File

@@ -110,8 +110,10 @@ function mapAsyncIterable<T, U, R = undefined>(
>next : Symbol(AsyncIterator.next, Decl(lib.es2018.asynciterable.d.ts, --, --))
},
async return(): Promise<IteratorResult<U, R>> {
async return(value: R): Promise<IteratorResult<U, R>> {
>return : Symbol(return, Decl(discriminateWithOptionalProperty2.ts, 32, 6))
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 33, 17))
>R : Symbol(R, Decl(discriminateWithOptionalProperty2.ts, 4, 31))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
>IteratorResult : Symbol(IteratorResult, Decl(lib.es2015.iterable.d.ts, --, --))
>U : Symbol(U, Decl(discriminateWithOptionalProperty2.ts, 4, 28))
@@ -122,11 +124,12 @@ function mapAsyncIterable<T, U, R = undefined>(
>iterator : Symbol(iterator, Decl(discriminateWithOptionalProperty2.ts, 8, 7))
>return : Symbol(AsyncIterator.return, Decl(lib.es2018.asynciterable.d.ts, --, --))
? mapResult(await iterator.return())
? mapResult(await iterator.return(value))
>mapResult : Symbol(mapResult, Decl(discriminateWithOptionalProperty2.ts, 8, 52))
>iterator.return : Symbol(AsyncIterator.return, Decl(lib.es2018.asynciterable.d.ts, --, --))
>iterator : Symbol(iterator, Decl(discriminateWithOptionalProperty2.ts, 8, 7))
>return : Symbol(AsyncIterator.return, Decl(lib.es2018.asynciterable.d.ts, --, --))
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 33, 17))
: { value: undefined as any, done: true };
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 36, 11))
@@ -164,35 +167,47 @@ function mapAsyncIterable<T, U, R = undefined>(
>this : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
},
async [Symbol.asyncDispose]() {
>[Symbol.asyncDispose] : Symbol([Symbol.asyncDispose], Decl(discriminateWithOptionalProperty2.ts, 46, 6))
>Symbol.asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.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, --, --))
>asyncDispose : Symbol(SymbolConstructor.asyncDispose, Decl(lib.esnext.disposable.d.ts, --, --))
await this.return(undefined!);
>this.return : Symbol(AsyncGenerator.return, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
>this : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
>return : Symbol(AsyncGenerator.return, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
>undefined : Symbol(undefined)
}
};
}
const items = [1, 2, 3];
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 50, 5))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 53, 5))
const iterable = {
>iterable : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 52, 5))
>iterable : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 55, 5))
[Symbol.asyncIterator]() {
>[Symbol.asyncIterator] : Symbol([Symbol.asyncIterator], Decl(discriminateWithOptionalProperty2.ts, 52, 18))
>[Symbol.asyncIterator] : Symbol([Symbol.asyncIterator], Decl(discriminateWithOptionalProperty2.ts, 55, 18))
>Symbol.asyncIterator : Symbol(SymbolConstructor.asyncIterator, Decl(lib.es2018.asynciterable.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, --, --))
>asyncIterator : Symbol(SymbolConstructor.asyncIterator, Decl(lib.es2018.asynciterable.d.ts, --, --))
return this;
>this : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 52, 16))
>this : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 55, 16))
},
next() {
>next : Symbol(next, Decl(discriminateWithOptionalProperty2.ts, 55, 4))
>next : Symbol(next, Decl(discriminateWithOptionalProperty2.ts, 58, 4))
const value = items[0];
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 57, 9))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 50, 5))
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 60, 9))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 53, 5))
items.shift();
>items.shift : Symbol(Array.shift, Decl(lib.es5.d.ts, --, --))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 50, 5))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 53, 5))
>shift : Symbol(Array.shift, Decl(lib.es5.d.ts, --, --))
return Promise.resolve({
@@ -201,23 +216,23 @@ const iterable = {
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
done: items.length === 0,
>done : Symbol(done, Decl(discriminateWithOptionalProperty2.ts, 59, 28))
>done : Symbol(done, Decl(discriminateWithOptionalProperty2.ts, 62, 28))
>items.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 50, 5))
>items : Symbol(items, Decl(discriminateWithOptionalProperty2.ts, 53, 5))
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
value,
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 60, 31))
>value : Symbol(value, Decl(discriminateWithOptionalProperty2.ts, 63, 31))
});
},
};
const doubles = mapAsyncIterable(iterable, (x) => x + x);
>doubles : Symbol(doubles, Decl(discriminateWithOptionalProperty2.ts, 66, 5))
>doubles : Symbol(doubles, Decl(discriminateWithOptionalProperty2.ts, 69, 5))
>mapAsyncIterable : Symbol(mapAsyncIterable, Decl(discriminateWithOptionalProperty2.ts, 2, 40))
>iterable : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 52, 5))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 66, 44))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 66, 44))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 66, 44))
>iterable : Symbol(iterable, Decl(discriminateWithOptionalProperty2.ts, 55, 5))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 69, 44))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 69, 44))
>x : Symbol(x, Decl(discriminateWithOptionalProperty2.ts, 69, 44))

View File

@@ -125,8 +125,8 @@ function mapAsyncIterable<T, U, R = undefined>(
}
return {
>{ async next() { return mapResult(await iterator.next()); }, async return(): Promise<IteratorResult<U, R>> { return typeof iterator.return === "function" ? mapResult(await iterator.return()) : { value: undefined as any, done: true }; }, async throw(error?: unknown) { if (typeof iterator.throw === "function") { return mapResult(await iterator.throw(error)); } throw error; }, [Symbol.asyncIterator]() { return this; }, } : { next(): Promise<IteratorResult<U, R>>; return(): Promise<IteratorResult<U, R>>; throw(error?: unknown): Promise<IteratorResult<U, R>>; [Symbol.asyncIterator](): AsyncGenerator<U, R, void>; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ async next() { return mapResult(await iterator.next()); }, async return(value: R): Promise<IteratorResult<U, R>> { return typeof iterator.return === "function" ? mapResult(await iterator.return(value)) : { value: undefined as any, done: true }; }, async throw(error?: unknown) { if (typeof iterator.throw === "function") { return mapResult(await iterator.throw(error)); } throw error; }, [Symbol.asyncIterator]() { return this; }, async [Symbol.asyncDispose]() { await this.return(undefined!); } } : { next(): Promise<IteratorResult<U, R>>; return(value: R): Promise<IteratorResult<U, R>>; throw(error?: unknown): Promise<IteratorResult<U, R>>; [Symbol.asyncIterator](): AsyncGenerator<U, R, void>; [Symbol.asyncDispose](): Promise<void>; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^ ^^^^^^^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
async next() {
>next : () => Promise<IteratorResult<U, R>>
@@ -149,13 +149,15 @@ function mapAsyncIterable<T, U, R = undefined>(
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
},
async return(): Promise<IteratorResult<U, R>> {
>return : () => Promise<IteratorResult<U, R>>
> : ^^^^^^
async return(value: R): Promise<IteratorResult<U, R>> {
>return : (value: R) => Promise<IteratorResult<U, R>>
> : ^ ^^ ^^^^^
>value : R
> : ^
return typeof iterator.return === "function"
>typeof iterator.return === "function" ? mapResult(await iterator.return()) : { value: undefined as any, done: true } : Promise<IteratorResult<U, R>> | { value: any; done: true; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
>typeof iterator.return === "function" ? mapResult(await iterator.return(value)) : { value: undefined as any, done: true } : Promise<IteratorResult<U, R>> | { value: any; done: true; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
>typeof iterator.return === "function" : boolean
> : ^^^^^^^
>typeof iterator.return : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
@@ -169,21 +171,23 @@ function mapAsyncIterable<T, U, R = undefined>(
>"function" : "function"
> : ^^^^^^^^^^
? mapResult(await iterator.return())
>mapResult(await iterator.return()) : Promise<IteratorResult<U, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
? mapResult(await iterator.return(value))
>mapResult(await iterator.return(value)) : Promise<IteratorResult<U, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>mapResult : (result: IteratorResult<T, R>) => Promise<IteratorResult<U, R>>
> : ^ ^^ ^^^^^
>await iterator.return() : IteratorResult<T, R>
> : ^^^^^^^^^^^^^^^^^^^^
>iterator.return() : Promise<IteratorResult<T, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>await iterator.return(value) : IteratorResult<T, R>
> : ^^^^^^^^^^^^^^^^^^^^
>iterator.return(value) : Promise<IteratorResult<T, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>iterator.return : (value?: R | PromiseLike<R> | undefined) => Promise<IteratorResult<T, R>>
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>iterator : AsyncIterator<T, R, undefined>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>return : (value?: R | PromiseLike<R> | undefined) => Promise<IteratorResult<T, R>>
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : R
> : ^
: { value: undefined as any, done: true };
>{ value: undefined as any, done: true } : { value: any; done: true; }
@@ -256,6 +260,32 @@ function mapAsyncIterable<T, U, R = undefined>(
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^
},
async [Symbol.asyncDispose]() {
>[Symbol.asyncDispose] : () => Promise<void>
> : ^^^^^^^^^^^^^^^^^^^
>Symbol.asyncDispose : unique symbol
> : ^^^^^^^^^^^^^
>Symbol : SymbolConstructor
> : ^^^^^^^^^^^^^^^^^
>asyncDispose : unique symbol
> : ^^^^^^^^^^^^^
await this.return(undefined!);
>await this.return(undefined!) : IteratorResult<U, R>
> : ^^^^^^^^^^^^^^^^^^^^
>this.return(undefined!) : Promise<IteratorResult<U, R>>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>this.return : (value: R | PromiseLike<R>) => Promise<IteratorResult<U, R>>
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>this : AsyncGenerator<U, R, void>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^
>return : (value: R | PromiseLike<R>) => Promise<IteratorResult<U, R>>
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>undefined! : never
> : ^^^^^
>undefined : undefined
> : ^^^^^^^^^
}
};
}

View File

@@ -0,0 +1,31 @@
usingDeclarationsWithIteratorObject.ts(20,17): error TS2850: The initializer of a 'using' declaration must be either an object with a '[Symbol.dispose]()' method, or be 'null' or 'undefined'.
Property '[Symbol.dispose]' is missing in type 'Iterator<string, undefined, any>' but required in type 'Disposable'.
==== usingDeclarationsWithIteratorObject.ts (1 errors) ====
declare const i: Iterator<string, undefined>;
declare const io: IteratorObject<string, undefined, unknown>;
declare const g: Generator<string, void>;
class MyIterator extends Iterator<string> {
next() { return { done: true, value: undefined }; }
}
function f() {
// should pass
using it0 = io;
using it1 = g;
using it2 = Iterator.from(i)
using it3 = new MyIterator();
using it4 = [].values();
using it5 = new Map<string, string>().entries();
using it6 = new Set<string>().keys();
// should fail
using it7 = i;
~
!!! error TS2850: The initializer of a 'using' declaration must be either an object with a '[Symbol.dispose]()' method, or be 'null' or 'undefined'.
!!! error TS2850: Property '[Symbol.dispose]' is missing in type 'Iterator<string, undefined, any>' but required in type 'Disposable'.
!!! related TS2728 lib.esnext.disposable.d.ts:--:--: '[Symbol.dispose]' is declared here.
}

View File

@@ -0,0 +1,72 @@
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsWithIteratorObject.ts] ////
=== usingDeclarationsWithIteratorObject.ts ===
declare const i: Iterator<string, undefined>;
>i : Symbol(i, Decl(usingDeclarationsWithIteratorObject.ts, 0, 13))
>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
declare const io: IteratorObject<string, undefined, unknown>;
>io : Symbol(io, Decl(usingDeclarationsWithIteratorObject.ts, 1, 13))
>IteratorObject : Symbol(IteratorObject, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.disposable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
declare const g: Generator<string, void>;
>g : Symbol(g, Decl(usingDeclarationsWithIteratorObject.ts, 2, 13))
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
class MyIterator extends Iterator<string> {
>MyIterator : Symbol(MyIterator, Decl(usingDeclarationsWithIteratorObject.ts, 2, 41))
>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
next() { return { done: true, value: undefined }; }
>next : Symbol(MyIterator.next, Decl(usingDeclarationsWithIteratorObject.ts, 4, 43))
>done : Symbol(done, Decl(usingDeclarationsWithIteratorObject.ts, 5, 21))
>value : Symbol(value, Decl(usingDeclarationsWithIteratorObject.ts, 5, 33))
>undefined : Symbol(undefined)
}
function f() {
>f : Symbol(f, Decl(usingDeclarationsWithIteratorObject.ts, 6, 1))
// should pass
using it0 = io;
>it0 : Symbol(it0, Decl(usingDeclarationsWithIteratorObject.ts, 10, 9))
>io : Symbol(io, Decl(usingDeclarationsWithIteratorObject.ts, 1, 13))
using it1 = g;
>it1 : Symbol(it1, Decl(usingDeclarationsWithIteratorObject.ts, 11, 9))
>g : Symbol(g, Decl(usingDeclarationsWithIteratorObject.ts, 2, 13))
using it2 = Iterator.from(i)
>it2 : Symbol(it2, Decl(usingDeclarationsWithIteratorObject.ts, 12, 9))
>Iterator.from : Symbol(IteratorConstructor.from, Decl(lib.esnext.iterator.d.ts, --, --))
>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
>from : Symbol(IteratorConstructor.from, Decl(lib.esnext.iterator.d.ts, --, --))
>i : Symbol(i, Decl(usingDeclarationsWithIteratorObject.ts, 0, 13))
using it3 = new MyIterator();
>it3 : Symbol(it3, Decl(usingDeclarationsWithIteratorObject.ts, 13, 9))
>MyIterator : Symbol(MyIterator, Decl(usingDeclarationsWithIteratorObject.ts, 2, 41))
using it4 = [].values();
>it4 : Symbol(it4, Decl(usingDeclarationsWithIteratorObject.ts, 14, 9))
>[].values : Symbol(Array.values, Decl(lib.es2015.iterable.d.ts, --, --))
>values : Symbol(Array.values, Decl(lib.es2015.iterable.d.ts, --, --))
using it5 = new Map<string, string>().entries();
>it5 : Symbol(it5, Decl(usingDeclarationsWithIteratorObject.ts, 15, 9))
>new Map<string, string>().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, --, --))
>entries : Symbol(Map.entries, Decl(lib.es2015.iterable.d.ts, --, --))
using it6 = new Set<string>().keys();
>it6 : Symbol(it6, Decl(usingDeclarationsWithIteratorObject.ts, 16, 9))
>new Set<string>().keys : Symbol(Set.keys, Decl(lib.es2015.iterable.d.ts, --, --))
>Set : Symbol(Set, 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, --, --))
>keys : Symbol(Set.keys, Decl(lib.es2015.iterable.d.ts, --, --))
// should fail
using it7 = i;
>it7 : Symbol(it7, Decl(usingDeclarationsWithIteratorObject.ts, 19, 9))
>i : Symbol(i, Decl(usingDeclarationsWithIteratorObject.ts, 0, 13))
}

View File

@@ -0,0 +1,123 @@
//// [tests/cases/conformance/statements/VariableStatements/usingDeclarations/usingDeclarationsWithIteratorObject.ts] ////
=== usingDeclarationsWithIteratorObject.ts ===
declare const i: Iterator<string, undefined>;
>i : Iterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
declare const io: IteratorObject<string, undefined, unknown>;
>io : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
declare const g: Generator<string, void>;
>g : Generator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyIterator extends Iterator<string> {
>MyIterator : MyIterator
> : ^^^^^^^^^^
>Iterator : Iterator<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
next() { return { done: true, value: undefined }; }
>next : () => { done: boolean; value: any; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ done: true, value: undefined } : { done: boolean; value: undefined; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>done : boolean
> : ^^^^^^^
>true : true
> : ^^^^
>value : undefined
> : ^^^^^^^^^
>undefined : undefined
> : ^^^^^^^^^
}
function f() {
>f : () => void
> : ^^^^^^^^^^
// should pass
using it0 = io;
>it0 : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>io : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
using it1 = g;
>it1 : Generator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>g : Generator<string, void, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
using it2 = Iterator.from(i)
>it2 : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Iterator.from(i) : IteratorObject<string, undefined, unknown>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>Iterator.from : <T>(value: Iterator<T, unknown, undefined> | Iterable<T, unknown, undefined>) => IteratorObject<T, undefined, unknown>
> : ^ ^^ ^^ ^^^^^
>Iterator : IteratorConstructor
> : ^^^^^^^^^^^^^^^^^^^
>from : <T>(value: Iterator<T, unknown, undefined> | Iterable<T, unknown, undefined>) => IteratorObject<T, undefined, unknown>
> : ^ ^^ ^^ ^^^^^
>i : Iterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
using it3 = new MyIterator();
>it3 : MyIterator
> : ^^^^^^^^^^
>new MyIterator() : MyIterator
> : ^^^^^^^^^^
>MyIterator : typeof MyIterator
> : ^^^^^^^^^^^^^^^^^
using it4 = [].values();
>it4 : ArrayIterator<any>
> : ^^^^^^^^^^^^^^^^^^
>[].values() : ArrayIterator<any>
> : ^^^^^^^^^^^^^^^^^^
>[].values : () => ArrayIterator<any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^
>[] : undefined[]
> : ^^^^^^^^^^^
>values : () => ArrayIterator<any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^
using it5 = new Map<string, string>().entries();
>it5 : MapIterator<[string, string]>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>new Map<string, string>().entries() : MapIterator<[string, string]>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>new Map<string, string>().entries : () => MapIterator<[string, string]>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>new Map<string, string>() : Map<string, string>
> : ^^^^^^^^^^^^^^^^^^^
>Map : MapConstructor
> : ^^^^^^^^^^^^^^
>entries : () => MapIterator<[string, string]>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
using it6 = new Set<string>().keys();
>it6 : SetIterator<string>
> : ^^^^^^^^^^^^^^^^^^^
>new Set<string>().keys() : SetIterator<string>
> : ^^^^^^^^^^^^^^^^^^^
>new Set<string>().keys : () => SetIterator<string>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
>new Set<string>() : Set<string>
> : ^^^^^^^^^^^
>Set : SetConstructor
> : ^^^^^^^^^^^^^^
>keys : () => SetIterator<string>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
// should fail
using it7 = i;
>it7 : Iterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>i : Iterator<string, undefined, any>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}

View File

@@ -36,9 +36,9 @@ function mapAsyncIterable<T, U, R = undefined>(
async next() {
return mapResult(await iterator.next());
},
async return(): Promise<IteratorResult<U, R>> {
async return(value: R): Promise<IteratorResult<U, R>> {
return typeof iterator.return === "function"
? mapResult(await iterator.return())
? mapResult(await iterator.return(value))
: { value: undefined as any, done: true };
},
async throw(error?: unknown) {
@@ -50,6 +50,9 @@ function mapAsyncIterable<T, U, R = undefined>(
[Symbol.asyncIterator]() {
return this;
},
async [Symbol.asyncDispose]() {
await this.return(undefined!);
}
};
}

View File

@@ -0,0 +1,17 @@
// @target: esnext
// @module: esnext
// @lib: esnext
// @noEmit: true
declare const ai: AsyncIterator<string, undefined>;
declare const aio: AsyncIteratorObject<string, undefined, unknown>;
declare const ag: AsyncGenerator<string, void>;
async function f() {
// should pass
await using it0 = aio;
await using it1 = ag;
// should fail
await using it2 = ai;
}

View File

@@ -0,0 +1,26 @@
// @target: esnext
// @module: esnext
// @lib: esnext
// @noEmit: true
declare const i: Iterator<string, undefined>;
declare const io: IteratorObject<string, undefined, unknown>;
declare const g: Generator<string, void>;
class MyIterator extends Iterator<string> {
next() { return { done: true, value: undefined }; }
}
async function f() {
// should pass
await using it0 = io;
await using it1 = g;
await using it2 = Iterator.from(i)
await using it3 = new MyIterator();
await using it4 = [].values();
await using it5 = new Map<string, string>().entries();
await using it6 = new Set<string>().keys();
// should fail
await using it7 = i;
}

View File

@@ -0,0 +1,26 @@
// @target: esnext
// @module: esnext
// @lib: esnext
// @noEmit: true
declare const i: Iterator<string, undefined>;
declare const io: IteratorObject<string, undefined, unknown>;
declare const g: Generator<string, void>;
class MyIterator extends Iterator<string> {
next() { return { done: true, value: undefined }; }
}
function f() {
// should pass
using it0 = io;
using it1 = g;
using it2 = Iterator.from(i)
using it3 = new MyIterator();
using it4 = [].values();
using it5 = new Map<string, string>().entries();
using it6 = new Set<string>().keys();
// should fail
using it7 = i;
}