Avoid silentNeverType leaking into generator types inferred based on inner generic calls at yields (#62283)

This commit is contained in:
Mateusz Burzyński 2025-12-05 19:47:37 +01:00 committed by GitHub
parent 0752278137
commit 38d95c8001
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 382 additions and 15 deletions

View File

@ -2189,7 +2189,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
};
var anyIterationTypes = createIterationTypes(anyType, anyType, anyType);
var silentNeverIterationTypes = createIterationTypes(silentNeverType, silentNeverType, silentNeverType);
var asyncIterationTypesResolver: IterationTypesResolver = {
iterableCacheKey: "iterationTypesOfAsyncIterable",
@ -39230,7 +39229,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const nextTypes: Type[] = [];
const isAsync = (getFunctionFlags(func) & FunctionFlags.Async) !== 0;
forEachYieldExpression(func.body as Block, yieldExpression => {
let yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : undefinedWideningType;
let yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode && checkMode & ~CheckMode.SkipGenericFunctions) : undefinedWideningType;
if (yieldExpression.expression && isConstContext(yieldExpression.expression)) {
yieldExpressionType = getRegularTypeOfLiteralType(yieldExpressionType);
}
@ -39253,9 +39252,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function getYieldedTypeOfYieldExpression(node: YieldExpression, expressionType: Type, sentType: Type, isAsync: boolean): Type | undefined {
if (expressionType === silentNeverType) {
return silentNeverType;
}
const errorNode = node.expression || node;
// A `yield*` expression effectively yields everything that its operand yields
const yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(isAsync ? IterationUse.AsyncYieldStar : IterationUse.YieldStar, expressionType, sentType, errorNode) : expressionType;
@ -45859,9 +45855,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
*/
function getIterationTypesOfIterable(type: Type, use: IterationUse, errorNode: Node | undefined) {
type = getReducedType(type);
if (type === silentNeverType) {
return silentNeverIterationTypes;
}
if (isTypeAny(type)) {
return anyIterationTypes;
}

View File

@ -1,7 +1,21 @@
genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator.
genericCallAtYieldExpressionInGenericCall1.ts(56,8): error TS2345: Argument of type '<T>(value: T) => Generator<number, void, any>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
Call signature return types 'Generator<number, void, any>' and 'Generator<never, unknown, unknown>' are incompatible.
The types returned by 'next(...)' are incompatible between these types.
Type 'IteratorResult<number, void>' is not assignable to type 'IteratorResult<never, unknown>'.
Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorResult<never, unknown>'.
Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorYieldResult<never>'.
Type 'number' is not assignable to type 'never'.
genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of type '<T>(value: T) => Generator<number, void, any>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
Call signature return types 'Generator<number, void, any>' and 'Generator<never, unknown, unknown>' are incompatible.
The types returned by 'next(...)' are incompatible between these types.
Type 'IteratorResult<number, void>' is not assignable to type 'IteratorResult<never, unknown>'.
Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorResult<never, unknown>'.
Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorYieldResult<never>'.
Type 'number' is not assignable to type 'never'.
==== genericCallAtYieldExpressionInGenericCall1.ts (1 errors) ====
==== genericCallAtYieldExpressionInGenericCall1.ts (3 errors) ====
declare const inner: {
<A>(value: A): {
(): A;
@ -31,4 +45,57 @@ genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type '() =>
~~~~~~~~~~~~~
!!! error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator.
});
declare const inner3: {
<A>(value: A): {
(): A;
[Symbol.iterator](): {
next(...args: ReadonlyArray<any>): IteratorResult<number, A>;
};
};
};
declare function outer2<A, Y>(body: (value: A) => Generator<Y, any, any>): Y;
// number
const result1 = outer2(function* <T>(value: T) {
yield* inner3(value);
});
// number
const result2 = outer2(function* <T>(value: T) {
const x = inner3(value);
yield* x;
});
declare function outer3<A>(
body: (value: A) => Generator<never, unknown, unknown>,
): void;
// error
outer3(function* <T>(value: T) {
~~~~~~~~
!!! error TS2345: Argument of type '<T>(value: T) => Generator<number, void, any>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
!!! error TS2345: Call signature return types 'Generator<number, void, any>' and 'Generator<never, unknown, unknown>' are incompatible.
!!! error TS2345: The types returned by 'next(...)' are incompatible between these types.
!!! error TS2345: Type 'IteratorResult<number, void>' is not assignable to type 'IteratorResult<never, unknown>'.
!!! error TS2345: Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorResult<never, unknown>'.
!!! error TS2345: Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorYieldResult<never>'.
!!! error TS2345: Type 'number' is not assignable to type 'never'.
yield* inner3(value);
});
// error
outer3(function* <T>(value: T) {
~~~~~~~~
!!! error TS2345: Argument of type '<T>(value: T) => Generator<number, void, any>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
!!! error TS2345: Call signature return types 'Generator<number, void, any>' and 'Generator<never, unknown, unknown>' are incompatible.
!!! error TS2345: The types returned by 'next(...)' are incompatible between these types.
!!! error TS2345: Type 'IteratorResult<number, void>' is not assignable to type 'IteratorResult<never, unknown>'.
!!! error TS2345: Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorResult<never, unknown>'.
!!! error TS2345: Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorYieldResult<never>'.
!!! error TS2345: Type 'number' is not assignable to type 'never'.
const x = inner3(value);
yield* x;
});

View File

@ -91,3 +91,116 @@ outer(function* <T>(value: T) {
});
declare const inner3: {
>inner3 : Symbol(inner3, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 28, 13))
<A>(value: A): {
>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 29, 3))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 29, 6))
>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 29, 3))
(): A;
>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 29, 3))
[Symbol.iterator](): {
>[Symbol.iterator] : Symbol([Symbol.iterator], Decl(genericCallAtYieldExpressionInGenericCall1.ts, 30, 10))
>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, --, --))
next(...args: ReadonlyArray<any>): IteratorResult<number, A>;
>next : Symbol(next, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 31, 26))
>args : Symbol(args, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 32, 11))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --) ... and 3 more)
>IteratorResult : Symbol(IteratorResult, Decl(lib.es2015.iterable.d.ts, --, --))
>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 29, 3))
};
};
};
declare function outer2<A, Y>(body: (value: A) => Generator<Y, any, any>): Y;
>outer2 : Symbol(outer2, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 35, 2))
>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 37, 24))
>Y : Symbol(Y, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 37, 26))
>body : Symbol(body, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 37, 30))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 37, 37))
>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 37, 24))
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
>Y : Symbol(Y, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 37, 26))
>Y : Symbol(Y, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 37, 26))
// number
const result1 = outer2(function* <T>(value: T) {
>result1 : Symbol(result1, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 40, 5))
>outer2 : Symbol(outer2, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 35, 2))
>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 40, 34))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 40, 37))
>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 40, 34))
yield* inner3(value);
>inner3 : Symbol(inner3, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 28, 13))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 40, 37))
});
// number
const result2 = outer2(function* <T>(value: T) {
>result2 : Symbol(result2, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 45, 5))
>outer2 : Symbol(outer2, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 35, 2))
>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 45, 34))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 45, 37))
>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 45, 34))
const x = inner3(value);
>x : Symbol(x, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 46, 7))
>inner3 : Symbol(inner3, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 28, 13))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 45, 37))
yield* x;
>x : Symbol(x, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 46, 7))
});
declare function outer3<A>(
>outer3 : Symbol(outer3, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 48, 3))
>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 50, 24))
body: (value: A) => Generator<never, unknown, unknown>,
>body : Symbol(body, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 50, 27))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 51, 9))
>A : Symbol(A, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 50, 24))
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
): void;
// error
outer3(function* <T>(value: T) {
>outer3 : Symbol(outer3, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 48, 3))
>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 55, 18))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 55, 21))
>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 55, 18))
yield* inner3(value);
>inner3 : Symbol(inner3, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 28, 13))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 55, 21))
});
// error
outer3(function* <T>(value: T) {
>outer3 : Symbol(outer3, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 48, 3))
>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 60, 18))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 60, 21))
>T : Symbol(T, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 60, 18))
const x = inner3(value);
>x : Symbol(x, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 61, 7))
>inner3 : Symbol(inner3, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 28, 13))
>value : Symbol(value, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 60, 21))
yield* x;
>x : Symbol(x, Decl(genericCallAtYieldExpressionInGenericCall1.ts, 61, 7))
});

View File

@ -47,8 +47,8 @@ outer(function* <T>(value: T) {
> : ^^^^
>outer : <A>(body: (value: A) => Generator<any, any, any>) => void
> : ^ ^^ ^^ ^^^^^
>function* <T>(value: T) { const result = yield* inner(value); // ok} : <T>(value: T) => Generator<never, void, never>
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>function* <T>(value: T) { const result = yield* inner(value); // ok} : <T>(value: T) => Generator<any, void, any>
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : T
> : ^
@ -111,8 +111,8 @@ outer(function* <T>(value: T) {
> : ^^^^
>outer : <A>(body: (value: A) => Generator<any, any, any>) => void
> : ^ ^^ ^^ ^^^^^
>function* <T>(value: T) { const result = yield* inner2(value); // error} : <T>(value: T) => Generator<never, void, never>
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>function* <T>(value: T) { const result = yield* inner2(value); // error} : <T>(value: T) => Generator<any, void, any>
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : T
> : ^
@ -130,3 +130,160 @@ outer(function* <T>(value: T) {
});
declare const inner3: {
>inner3 : <A>(value: A) => { (): A; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, A>; }; }
> : ^ ^^ ^^ ^^^^^
<A>(value: A): {
>value : A
> : ^
(): A;
[Symbol.iterator](): {
>[Symbol.iterator] : () => { next(...args: ReadonlyArray<any>): IteratorResult<number, A>; }
> : ^^^^^^
>Symbol.iterator : unique symbol
> : ^^^^^^^^^^^^^
>Symbol : SymbolConstructor
> : ^^^^^^^^^^^^^^^^^
>iterator : unique symbol
> : ^^^^^^^^^^^^^
next(...args: ReadonlyArray<any>): IteratorResult<number, A>;
>next : (...args: ReadonlyArray<any>) => IteratorResult<number, A>
> : ^^^^ ^^ ^^^^^
>args : readonly any[]
> : ^^^^^^^^^^^^^^
};
};
};
declare function outer2<A, Y>(body: (value: A) => Generator<Y, any, any>): Y;
>outer2 : <A, Y>(body: (value: A) => Generator<Y, any, any>) => Y
> : ^ ^^ ^^ ^^ ^^^^^
>body : (value: A) => Generator<Y, any, any>
> : ^ ^^ ^^^^^
>value : A
> : ^
// number
const result1 = outer2(function* <T>(value: T) {
>result1 : number
> : ^^^^^^
>outer2(function* <T>(value: T) { yield* inner3(value);}) : number
> : ^^^^^^
>outer2 : <A, Y>(body: (value: A) => Generator<Y, any, any>) => Y
> : ^ ^^ ^^ ^^ ^^^^^
>function* <T>(value: T) { yield* inner3(value);} : <T>(value: T) => Generator<number, void, any>
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : T
> : ^
yield* inner3(value);
>yield* inner3(value) : T
> : ^
>inner3(value) : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, T>; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>inner3 : <A>(value: A) => { (): A; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, A>; }; }
> : ^ ^^ ^^ ^^^^^
>value : T
> : ^
});
// number
const result2 = outer2(function* <T>(value: T) {
>result2 : number
> : ^^^^^^
>outer2(function* <T>(value: T) { const x = inner3(value); yield* x;}) : number
> : ^^^^^^
>outer2 : <A, Y>(body: (value: A) => Generator<Y, any, any>) => Y
> : ^ ^^ ^^ ^^ ^^^^^
>function* <T>(value: T) { const x = inner3(value); yield* x;} : <T>(value: T) => Generator<number, void, any>
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : T
> : ^
const x = inner3(value);
>x : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, T>; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>inner3(value) : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, T>; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>inner3 : <A>(value: A) => { (): A; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, A>; }; }
> : ^ ^^ ^^ ^^^^^
>value : T
> : ^
yield* x;
>yield* x : T
> : ^
>x : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, T>; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
});
declare function outer3<A>(
>outer3 : <A>(body: (value: A) => Generator<never, unknown, unknown>) => void
> : ^ ^^ ^^ ^^^^^
body: (value: A) => Generator<never, unknown, unknown>,
>body : (value: A) => Generator<never, unknown, unknown>
> : ^ ^^ ^^^^^
>value : A
> : ^
): void;
// error
outer3(function* <T>(value: T) {
>outer3(function* <T>(value: T) { yield* inner3(value);}) : void
> : ^^^^
>outer3 : <A>(body: (value: A) => Generator<never, unknown, unknown>) => void
> : ^ ^^ ^^ ^^^^^
>function* <T>(value: T) { yield* inner3(value);} : <T>(value: T) => Generator<number, void, any>
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : T
> : ^
yield* inner3(value);
>yield* inner3(value) : T
> : ^
>inner3(value) : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, T>; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>inner3 : <A>(value: A) => { (): A; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, A>; }; }
> : ^ ^^ ^^ ^^^^^
>value : T
> : ^
});
// error
outer3(function* <T>(value: T) {
>outer3(function* <T>(value: T) { const x = inner3(value); yield* x;}) : void
> : ^^^^
>outer3 : <A>(body: (value: A) => Generator<never, unknown, unknown>) => void
> : ^ ^^ ^^ ^^^^^
>function* <T>(value: T) { const x = inner3(value); yield* x;} : <T>(value: T) => Generator<number, void, any>
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>value : T
> : ^
const x = inner3(value);
>x : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, T>; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>inner3(value) : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, T>; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>inner3 : <A>(value: A) => { (): A; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, A>; }; }
> : ^ ^^ ^^ ^^^^^
>value : T
> : ^
yield* x;
>yield* x : T
> : ^
>x : { (): T; [Symbol.iterator](): { next(...args: ReadonlyArray<any>): IteratorResult<number, T>; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
});

View File

@ -70,8 +70,8 @@ fn(function* <T>(queue: Enqueue<T>, value: T) {
> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>fn : <Eff extends Effect, AEff, Args extends Array<any>>(body: (...args: Args) => Generator<Eff, AEff, any>) => (...args: Args) => any
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^
>function* <T>(queue: Enqueue<T>, value: T) { yield* offer(queue, value);} : <T>(queue: Enqueue<T>, value: T) => Generator<never, void, never>
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>function* <T>(queue: Enqueue<T>, value: T) { yield* offer(queue, value);} : <T>(queue: Enqueue<T>, value: T) => Generator<any, void, any>
> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>queue : Enqueue<T>
> : ^^^^^^^^^^
>value : T

View File

@ -30,3 +30,40 @@ declare const inner2: {
outer(function* <T>(value: T) {
const result = yield* inner2(value); // error
});
declare const inner3: {
<A>(value: A): {
(): A;
[Symbol.iterator](): {
next(...args: ReadonlyArray<any>): IteratorResult<number, A>;
};
};
};
declare function outer2<A, Y>(body: (value: A) => Generator<Y, any, any>): Y;
// number
const result1 = outer2(function* <T>(value: T) {
yield* inner3(value);
});
// number
const result2 = outer2(function* <T>(value: T) {
const x = inner3(value);
yield* x;
});
declare function outer3<A>(
body: (value: A) => Generator<never, unknown, unknown>,
): void;
// error
outer3(function* <T>(value: T) {
yield* inner3(value);
});
// error
outer3(function* <T>(value: T) {
const x = inner3(value);
yield* x;
});