-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Closed
Labels
BugA bug in TypeScriptA bug in TypeScriptFix AvailableA PR has been opened for this issueA PR has been opened for this issue
Milestone
Description
🔎 Search Terms
async generator inference, async generator
🕗 Version & Regression Information
- This is a crash
- This changed between versions 4.0.5 and 5.4.3
- This changed in commit or PR _______
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
- I was unable to test this on prior versions because _______
⏯ Playground Link
💻 Code
interface Result<T, E> {
[Symbol.iterator](): Generator<E, T>
}
type NotResultOf<T> = T extends Result<any, any> ? never : T;
type ErrTypeOf<T> = T extends Result<unknown, infer E> ? E : never;
type OkTypeOf<T> = T extends Result<infer R, unknown> ? R : never;
type AsyncJob<T, E> = () => AsyncGenerator<E, T>;
declare const asyncDo: <T, E>(job: AsyncJob<T, E>) => Promise<Result<
OkTypeOf<T> | NotResultOf<T>,
E | ErrTypeOf<T>
>>;
declare const mapErr: <E, F>(mapper: (error: E) => F) => <T>(result: Result<T, E>) => Result<T, F>;
type Book = { id: string; title: string; authorId: string };
type Author = { id: string; name: string };
type BookWithAuthor = Book & { author: Author };
declare const fetchBook: (id: string) => Promise<Result<Book, "NOT_FOUND">>;
declare const fetchAuthor: (id: string) => Promise<Result<Author, "NOT_FOUND">>;
export const fetchBookWithAuthor1 =
(bookId: string) =>
asyncDo(async function* () {
const book: Book = yield* await fetchBook(bookId)
.then(mapErr(() => "NOT_FOUND_BOOK" as const))
const author: Author = yield* await fetchAuthor(book.authorId)
.then(mapErr(() => "NOT_FOUND_AUTHOR" as const))
return { ...book, author } as BookWithAuthor;
});
export const fetchBookWithAuthor2 =
(bookId: string): Promise<Result<BookWithAuthor, "NOT_FOUND_BOOK" | "NOT_FOUND_AUTHOR">> =>
asyncDo(async function* () {
const book: Book = yield* await fetchBook(bookId)
.then(mapErr(() => "NOT_FOUND_BOOK" as const))
const author: Author = yield* await fetchAuthor(book.authorId)
.then(mapErr(() => "NOT_FOUND_AUTHOR" as const))
return { ...book, author } as BookWithAuthor;
});
🙁 Actual behavior
Compilation Error in the function fetchBookWithAuthor2
Type 'Author | BookWithAuthor' is not assignable to type 'Author'.
Property 'name' is missing in type 'BookWithAuthor' but required in type 'Author'.(2322)
input.ts(17, 29): 'name' is declared here.
🙂 Expected behavior
No errors.
compilation result must be the same as for fetchBookWithAuthor1
.
The only difference between two versions of the function is a return type specified.
The defenition file is emitted correctly:
interface Result<T, E> {
[Symbol.iterator](): Generator<E, T>;
}
type Book = {
id: string;
title: string;
authorId: string;
};
type Author = {
id: string;
name: string;
};
type BookWithAuthor = Book & {
author: Author;
};
export declare const fetchBookWithAuthor1: (bookId: string) => Promise<Result<BookWithAuthor, "NOT_FOUND_BOOK" | "NOT_FOUND_AUTHOR">>;
export declare const fetchBookWithAuthor2: (bookId: string) => Promise<Result<BookWithAuthor, "NOT_FOUND_BOOK" | "NOT_FOUND_AUTHOR">>;
export {};
Additional information about the issue
No response
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScriptFix AvailableA PR has been opened for this issueA PR has been opened for this issue