mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Do not infer yield* type from contextual TReturn (#58621)
This commit is contained in:
parent
2a9e4b8aa2
commit
718d79807c
@ -30915,9 +30915,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (!node.asteriskToken && contextualReturnType.flags & TypeFlags.Union) {
|
||||
contextualReturnType = filterType(contextualReturnType, type => !!getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, type, isAsyncGenerator));
|
||||
}
|
||||
return node.asteriskToken
|
||||
? contextualReturnType
|
||||
: getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, contextualReturnType, isAsyncGenerator);
|
||||
if (node.asteriskToken) {
|
||||
const iterationTypes = getIterationTypesOfGeneratorFunctionReturnType(contextualReturnType, isAsyncGenerator);
|
||||
const yieldType = iterationTypes?.yieldType ?? silentNeverType;
|
||||
const returnType = getContextualType(node, contextFlags) ?? silentNeverType;
|
||||
const nextType = iterationTypes?.nextType ?? unknownType;
|
||||
const generatorType = createGeneratorType(yieldType, returnType, nextType, /*isAsyncGenerator*/ false);
|
||||
if (isAsyncGenerator) {
|
||||
const asyncGeneratorType = createGeneratorType(yieldType, returnType, nextType, /*isAsyncGenerator*/ true);
|
||||
return getUnionType([generatorType, asyncGeneratorType]);
|
||||
}
|
||||
return generatorType;
|
||||
}
|
||||
return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, contextualReturnType, isAsyncGenerator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -37829,7 +37839,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
if (isGenerator) {
|
||||
return createGeneratorReturnType(
|
||||
return createGeneratorType(
|
||||
yieldType || neverType,
|
||||
returnType || fallbackReturnType,
|
||||
nextType || getContextualIterationType(IterationTypeKind.Next, func) || unknownType,
|
||||
@ -37846,7 +37856,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
function createGeneratorReturnType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) {
|
||||
function createGeneratorType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) {
|
||||
const resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
|
||||
const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false);
|
||||
yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType;
|
||||
@ -40648,7 +40658,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const generatorYieldType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, returnType, (functionFlags & FunctionFlags.Async) !== 0) || anyType;
|
||||
const generatorReturnType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, (functionFlags & FunctionFlags.Async) !== 0) || generatorYieldType;
|
||||
const generatorNextType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, returnType, (functionFlags & FunctionFlags.Async) !== 0) || unknownType;
|
||||
const generatorInstantiation = createGeneratorReturnType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags & FunctionFlags.Async));
|
||||
const generatorInstantiation = createGeneratorType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags & FunctionFlags.Async));
|
||||
|
||||
return checkTypeAssignableTo(generatorInstantiation, returnType, errorNode);
|
||||
}
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
//// [tests/cases/compiler/asyncYieldStarContextualType.ts] ////
|
||||
|
||||
=== asyncYieldStarContextualType.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/57903
|
||||
interface Result<T, E> {
|
||||
>Result : Symbol(Result, Decl(asyncYieldStarContextualType.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(asyncYieldStarContextualType.ts, 1, 17))
|
||||
>E : Symbol(E, Decl(asyncYieldStarContextualType.ts, 1, 19))
|
||||
|
||||
[Symbol.iterator](): Generator<E, T, unknown>
|
||||
>[Symbol.iterator] : Symbol(Result[Symbol.iterator], Decl(asyncYieldStarContextualType.ts, 1, 24))
|
||||
>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, --, --))
|
||||
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
|
||||
>E : Symbol(E, Decl(asyncYieldStarContextualType.ts, 1, 19))
|
||||
>T : Symbol(T, Decl(asyncYieldStarContextualType.ts, 1, 17))
|
||||
}
|
||||
|
||||
type Book = { id: string; title: string; authorId: string };
|
||||
>Book : Symbol(Book, Decl(asyncYieldStarContextualType.ts, 3, 1))
|
||||
>id : Symbol(id, Decl(asyncYieldStarContextualType.ts, 5, 13))
|
||||
>title : Symbol(title, Decl(asyncYieldStarContextualType.ts, 5, 25))
|
||||
>authorId : Symbol(authorId, Decl(asyncYieldStarContextualType.ts, 5, 40))
|
||||
|
||||
type Author = { id: string; name: string };
|
||||
>Author : Symbol(Author, Decl(asyncYieldStarContextualType.ts, 5, 60))
|
||||
>id : Symbol(id, Decl(asyncYieldStarContextualType.ts, 6, 15))
|
||||
>name : Symbol(name, Decl(asyncYieldStarContextualType.ts, 6, 27))
|
||||
|
||||
type BookWithAuthor = Book & { author: Author };
|
||||
>BookWithAuthor : Symbol(BookWithAuthor, Decl(asyncYieldStarContextualType.ts, 6, 43))
|
||||
>Book : Symbol(Book, Decl(asyncYieldStarContextualType.ts, 3, 1))
|
||||
>author : Symbol(author, Decl(asyncYieldStarContextualType.ts, 7, 30))
|
||||
>Author : Symbol(Author, Decl(asyncYieldStarContextualType.ts, 5, 60))
|
||||
|
||||
declare const authorPromise: Promise<Result<Author, "NOT_FOUND_AUTHOR">>;
|
||||
>authorPromise : Symbol(authorPromise, Decl(asyncYieldStarContextualType.ts, 9, 13))
|
||||
>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, --, --))
|
||||
>Result : Symbol(Result, Decl(asyncYieldStarContextualType.ts, 0, 0))
|
||||
>Author : Symbol(Author, Decl(asyncYieldStarContextualType.ts, 5, 60))
|
||||
|
||||
declare const mapper: <T>(result: Result<T, "NOT_FOUND_AUTHOR">) => Result<T, "NOT_FOUND_AUTHOR">;
|
||||
>mapper : Symbol(mapper, Decl(asyncYieldStarContextualType.ts, 10, 13))
|
||||
>T : Symbol(T, Decl(asyncYieldStarContextualType.ts, 10, 23))
|
||||
>result : Symbol(result, Decl(asyncYieldStarContextualType.ts, 10, 26))
|
||||
>Result : Symbol(Result, Decl(asyncYieldStarContextualType.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(asyncYieldStarContextualType.ts, 10, 23))
|
||||
>Result : Symbol(Result, Decl(asyncYieldStarContextualType.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(asyncYieldStarContextualType.ts, 10, 23))
|
||||
|
||||
declare const g: <T, U, V>() => AsyncGenerator<T, U, V>;
|
||||
>g : Symbol(g, Decl(asyncYieldStarContextualType.ts, 11, 13))
|
||||
>T : Symbol(T, Decl(asyncYieldStarContextualType.ts, 11, 18))
|
||||
>U : Symbol(U, Decl(asyncYieldStarContextualType.ts, 11, 20))
|
||||
>V : Symbol(V, Decl(asyncYieldStarContextualType.ts, 11, 23))
|
||||
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(asyncYieldStarContextualType.ts, 11, 18))
|
||||
>U : Symbol(U, Decl(asyncYieldStarContextualType.ts, 11, 20))
|
||||
>V : Symbol(V, Decl(asyncYieldStarContextualType.ts, 11, 23))
|
||||
|
||||
async function* f(): AsyncGenerator<"NOT_FOUND_AUTHOR" | "NOT_FOUND_BOOK", BookWithAuthor, unknown> {
|
||||
>f : Symbol(f, Decl(asyncYieldStarContextualType.ts, 11, 56))
|
||||
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
|
||||
>BookWithAuthor : Symbol(BookWithAuthor, Decl(asyncYieldStarContextualType.ts, 6, 43))
|
||||
|
||||
// Without yield*, the type of test1 is
|
||||
// Result<Author, "NOT_FOUND_AUTHOR>
|
||||
const test1 = await authorPromise.then(mapper)
|
||||
>test1 : Symbol(test1, Decl(asyncYieldStarContextualType.ts, 16, 9))
|
||||
>authorPromise.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>authorPromise : Symbol(authorPromise, Decl(asyncYieldStarContextualType.ts, 9, 13))
|
||||
>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>mapper : Symbol(mapper, Decl(asyncYieldStarContextualType.ts, 10, 13))
|
||||
|
||||
// With yield*, the type of test2 is
|
||||
// Author | BookWithAuthor
|
||||
// But this codepath has no way to produce BookWithAuthor
|
||||
const test2 = yield* await authorPromise.then(mapper)
|
||||
>test2 : Symbol(test2, Decl(asyncYieldStarContextualType.ts, 21, 9))
|
||||
>authorPromise.then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>authorPromise : Symbol(authorPromise, Decl(asyncYieldStarContextualType.ts, 9, 13))
|
||||
>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --))
|
||||
>mapper : Symbol(mapper, Decl(asyncYieldStarContextualType.ts, 10, 13))
|
||||
|
||||
const x1 = yield* g();
|
||||
>x1 : Symbol(x1, Decl(asyncYieldStarContextualType.ts, 23, 9))
|
||||
>g : Symbol(g, Decl(asyncYieldStarContextualType.ts, 11, 13))
|
||||
|
||||
const x2: number = yield* g();
|
||||
>x2 : Symbol(x2, Decl(asyncYieldStarContextualType.ts, 24, 9))
|
||||
>g : Symbol(g, Decl(asyncYieldStarContextualType.ts, 11, 13))
|
||||
|
||||
return null! as BookWithAuthor;
|
||||
>BookWithAuthor : Symbol(BookWithAuthor, Decl(asyncYieldStarContextualType.ts, 6, 43))
|
||||
}
|
||||
123
tests/baselines/reference/asyncYieldStarContextualType.types
Normal file
123
tests/baselines/reference/asyncYieldStarContextualType.types
Normal file
@ -0,0 +1,123 @@
|
||||
//// [tests/cases/compiler/asyncYieldStarContextualType.ts] ////
|
||||
|
||||
=== asyncYieldStarContextualType.ts ===
|
||||
// https://github.com/microsoft/TypeScript/issues/57903
|
||||
interface Result<T, E> {
|
||||
[Symbol.iterator](): Generator<E, T, unknown>
|
||||
>[Symbol.iterator] : () => Generator<E, T, unknown>
|
||||
> : ^^^^^^
|
||||
>Symbol.iterator : unique symbol
|
||||
> : ^^^^^^^^^^^^^
|
||||
>Symbol : SymbolConstructor
|
||||
> : ^^^^^^^^^^^^^^^^^
|
||||
>iterator : unique symbol
|
||||
> : ^^^^^^^^^^^^^
|
||||
}
|
||||
|
||||
type Book = { id: string; title: string; authorId: string };
|
||||
>Book : Book
|
||||
> : ^^^^
|
||||
>id : string
|
||||
> : ^^^^^^
|
||||
>title : string
|
||||
> : ^^^^^^
|
||||
>authorId : string
|
||||
> : ^^^^^^
|
||||
|
||||
type Author = { id: string; name: string };
|
||||
>Author : Author
|
||||
> : ^^^^^^
|
||||
>id : string
|
||||
> : ^^^^^^
|
||||
>name : string
|
||||
> : ^^^^^^
|
||||
|
||||
type BookWithAuthor = Book & { author: Author };
|
||||
>BookWithAuthor : BookWithAuthor
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>author : Author
|
||||
> : ^^^^^^
|
||||
|
||||
declare const authorPromise: Promise<Result<Author, "NOT_FOUND_AUTHOR">>;
|
||||
>authorPromise : Promise<Result<Author, "NOT_FOUND_AUTHOR">>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
declare const mapper: <T>(result: Result<T, "NOT_FOUND_AUTHOR">) => Result<T, "NOT_FOUND_AUTHOR">;
|
||||
>mapper : <T>(result: Result<T, "NOT_FOUND_AUTHOR">) => Result<T, "NOT_FOUND_AUTHOR">
|
||||
> : ^ ^^ ^^ ^^^^^
|
||||
>result : Result<T, "NOT_FOUND_AUTHOR">
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
declare const g: <T, U, V>() => AsyncGenerator<T, U, V>;
|
||||
>g : <T, U, V>() => AsyncGenerator<T, U, V>
|
||||
> : ^ ^^ ^^ ^^^^^^^
|
||||
|
||||
async function* f(): AsyncGenerator<"NOT_FOUND_AUTHOR" | "NOT_FOUND_BOOK", BookWithAuthor, unknown> {
|
||||
>f : () => AsyncGenerator<"NOT_FOUND_AUTHOR" | "NOT_FOUND_BOOK", BookWithAuthor, unknown>
|
||||
> : ^^^^^^
|
||||
|
||||
// Without yield*, the type of test1 is
|
||||
// Result<Author, "NOT_FOUND_AUTHOR>
|
||||
const test1 = await authorPromise.then(mapper)
|
||||
>test1 : Result<Author, "NOT_FOUND_AUTHOR">
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>await authorPromise.then(mapper) : Result<Author, "NOT_FOUND_AUTHOR">
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>authorPromise.then(mapper) : Promise<Result<Author, "NOT_FOUND_AUTHOR">>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>authorPromise.then : <TResult1 = Result<Author, "NOT_FOUND_AUTHOR">, TResult2 = never>(onfulfilled?: (value: Result<Author, "NOT_FOUND_AUTHOR">) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>authorPromise : Promise<Result<Author, "NOT_FOUND_AUTHOR">>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>then : <TResult1 = Result<Author, "NOT_FOUND_AUTHOR">, TResult2 = never>(onfulfilled?: (value: Result<Author, "NOT_FOUND_AUTHOR">) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>mapper : <T>(result: Result<T, "NOT_FOUND_AUTHOR">) => Result<T, "NOT_FOUND_AUTHOR">
|
||||
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
// With yield*, the type of test2 is
|
||||
// Author | BookWithAuthor
|
||||
// But this codepath has no way to produce BookWithAuthor
|
||||
const test2 = yield* await authorPromise.then(mapper)
|
||||
>test2 : Author
|
||||
> : ^^^^^^
|
||||
>yield* await authorPromise.then(mapper) : Author
|
||||
> : ^^^^^^
|
||||
>await authorPromise.then(mapper) : Result<Author, "NOT_FOUND_AUTHOR">
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>authorPromise.then(mapper) : Promise<Result<Author, "NOT_FOUND_AUTHOR">>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>authorPromise.then : <TResult1 = Result<Author, "NOT_FOUND_AUTHOR">, TResult2 = never>(onfulfilled?: (value: Result<Author, "NOT_FOUND_AUTHOR">) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>authorPromise : Promise<Result<Author, "NOT_FOUND_AUTHOR">>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>then : <TResult1 = Result<Author, "NOT_FOUND_AUTHOR">, TResult2 = never>(onfulfilled?: (value: Result<Author, "NOT_FOUND_AUTHOR">) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<TResult1 | TResult2>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>mapper : <T>(result: Result<T, "NOT_FOUND_AUTHOR">) => Result<T, "NOT_FOUND_AUTHOR">
|
||||
> : ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
const x1 = yield* g();
|
||||
>x1 : unknown
|
||||
> : ^^^^^^^
|
||||
>yield* g() : unknown
|
||||
> : ^^^^^^^
|
||||
>g() : AsyncGenerator<"NOT_FOUND_AUTHOR" | "NOT_FOUND_BOOK", unknown, unknown>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>g : <T, U, V>() => AsyncGenerator<T, U, V>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
const x2: number = yield* g();
|
||||
>x2 : number
|
||||
> : ^^^^^^
|
||||
>yield* g() : number
|
||||
> : ^^^^^^
|
||||
>g() : AsyncGenerator<"NOT_FOUND_AUTHOR" | "NOT_FOUND_BOOK", number, unknown>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>g : <T, U, V>() => AsyncGenerator<T, U, V>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
return null! as BookWithAuthor;
|
||||
>null! as BookWithAuthor : BookWithAuthor
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>null! : null
|
||||
> : ^^^^
|
||||
}
|
||||
25
tests/baselines/reference/yieldStarContextualType.symbols
Normal file
25
tests/baselines/reference/yieldStarContextualType.symbols
Normal file
@ -0,0 +1,25 @@
|
||||
//// [tests/cases/compiler/yieldStarContextualType.ts] ////
|
||||
|
||||
=== yieldStarContextualType.ts ===
|
||||
declare const g: <T, U, V>() => Generator<T, U, V>;
|
||||
>g : Symbol(g, Decl(yieldStarContextualType.ts, 0, 13))
|
||||
>T : Symbol(T, Decl(yieldStarContextualType.ts, 0, 18))
|
||||
>U : Symbol(U, Decl(yieldStarContextualType.ts, 0, 20))
|
||||
>V : Symbol(V, Decl(yieldStarContextualType.ts, 0, 23))
|
||||
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(yieldStarContextualType.ts, 0, 18))
|
||||
>U : Symbol(U, Decl(yieldStarContextualType.ts, 0, 20))
|
||||
>V : Symbol(V, Decl(yieldStarContextualType.ts, 0, 23))
|
||||
|
||||
function* f(): Generator<string, void, unknown> {
|
||||
>f : Symbol(f, Decl(yieldStarContextualType.ts, 0, 51))
|
||||
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
|
||||
|
||||
const x1 = yield* g();
|
||||
>x1 : Symbol(x1, Decl(yieldStarContextualType.ts, 3, 9))
|
||||
>g : Symbol(g, Decl(yieldStarContextualType.ts, 0, 13))
|
||||
|
||||
const x2: number = yield* g();
|
||||
>x2 : Symbol(x2, Decl(yieldStarContextualType.ts, 4, 9))
|
||||
>g : Symbol(g, Decl(yieldStarContextualType.ts, 0, 13))
|
||||
}
|
||||
31
tests/baselines/reference/yieldStarContextualType.types
Normal file
31
tests/baselines/reference/yieldStarContextualType.types
Normal file
@ -0,0 +1,31 @@
|
||||
//// [tests/cases/compiler/yieldStarContextualType.ts] ////
|
||||
|
||||
=== yieldStarContextualType.ts ===
|
||||
declare const g: <T, U, V>() => Generator<T, U, V>;
|
||||
>g : <T, U, V>() => Generator<T, U, V>
|
||||
> : ^ ^^ ^^ ^^^^^^^
|
||||
|
||||
function* f(): Generator<string, void, unknown> {
|
||||
>f : () => Generator<string, void, unknown>
|
||||
> : ^^^^^^
|
||||
|
||||
const x1 = yield* g();
|
||||
>x1 : unknown
|
||||
> : ^^^^^^^
|
||||
>yield* g() : unknown
|
||||
> : ^^^^^^^
|
||||
>g() : Generator<string, unknown, unknown>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>g : <T, U, V>() => Generator<T, U, V>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
const x2: number = yield* g();
|
||||
>x2 : number
|
||||
> : ^^^^^^
|
||||
>yield* g() : number
|
||||
> : ^^^^^^
|
||||
>g() : Generator<string, number, unknown>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>g : <T, U, V>() => Generator<T, U, V>
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
}
|
||||
31
tests/cases/compiler/asyncYieldStarContextualType.ts
Normal file
31
tests/cases/compiler/asyncYieldStarContextualType.ts
Normal file
@ -0,0 +1,31 @@
|
||||
// @target: esnext
|
||||
// @noEmit: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/57903
|
||||
interface Result<T, E> {
|
||||
[Symbol.iterator](): Generator<E, T, unknown>
|
||||
}
|
||||
|
||||
type Book = { id: string; title: string; authorId: string };
|
||||
type Author = { id: string; name: string };
|
||||
type BookWithAuthor = Book & { author: Author };
|
||||
|
||||
declare const authorPromise: Promise<Result<Author, "NOT_FOUND_AUTHOR">>;
|
||||
declare const mapper: <T>(result: Result<T, "NOT_FOUND_AUTHOR">) => Result<T, "NOT_FOUND_AUTHOR">;
|
||||
declare const g: <T, U, V>() => AsyncGenerator<T, U, V>;
|
||||
|
||||
async function* f(): AsyncGenerator<"NOT_FOUND_AUTHOR" | "NOT_FOUND_BOOK", BookWithAuthor, unknown> {
|
||||
// Without yield*, the type of test1 is
|
||||
// Result<Author, "NOT_FOUND_AUTHOR>
|
||||
const test1 = await authorPromise.then(mapper)
|
||||
|
||||
// With yield*, the type of test2 is
|
||||
// Author | BookWithAuthor
|
||||
// But this codepath has no way to produce BookWithAuthor
|
||||
const test2 = yield* await authorPromise.then(mapper)
|
||||
|
||||
const x1 = yield* g();
|
||||
const x2: number = yield* g();
|
||||
|
||||
return null! as BookWithAuthor;
|
||||
}
|
||||
9
tests/cases/compiler/yieldStarContextualType.ts
Normal file
9
tests/cases/compiler/yieldStarContextualType.ts
Normal file
@ -0,0 +1,9 @@
|
||||
// @target: esnext
|
||||
// @noEmit: true
|
||||
|
||||
declare const g: <T, U, V>() => Generator<T, U, V>;
|
||||
|
||||
function* f(): Generator<string, void, unknown> {
|
||||
const x1 = yield* g();
|
||||
const x2: number = yield* g();
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user