Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved Promise handling to support packages like Prisma #1923

Open
arthurfiorette opened this issue Apr 16, 2024 · 1 comment · May be fixed by #1924
Open

Improved Promise handling to support packages like Prisma #1923

arthurfiorette opened this issue Apr 16, 2024 · 1 comment · May be fixed by #1924

Comments

@arthurfiorette
Copy link
Contributor

At #1386, I added basic support for Promise unwrapping. Since then promises have evolved and types like Awaited have been added and a awaited api have been added in the tsc api.

I think the most evident use case is with Prisma, which all ORM methods return a PrismaPromise class:

export declare interface PrismaPromise<T> extends Promise<T> {
    [Symbol.toStringTag]: 'PrismaPromise';
}

Every type, just by extending or having the Promise as a base type, when used inside a async function or within the Awaited type, gets unwraped:

The above example with prisma can be represented in the following way:

image

image

checker.getAwaitedType api exists, but is unfortunately not yet public. https://github.com/nonara/ts-expose-internals can be set up to help us.

My current test case of nodes to be supported is the following:

export type Original = { a: string; b: number[] };

export type PromiseAlias = Promise<Original>;

export class PromiseClass extends Promise<Original> {}

export interface PromiseInterface extends Promise<Original> {}

export type LikeType = PromiseLike<Original>;

export class LikeClass implements PromiseLike<Original> {
    then<TResult1 = Original, TResult2 = never>(
        onfulfilled?: ((value: Original) => TResult1 | PromiseLike<TResult1>) | null | undefined,
        onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
    ): PromiseLike<TResult1 | TResult2> {
        return {} as any;
    }
}

export abstract class LikeAbstractClass implements PromiseLike<Original> {
    abstract then<TResult1 = Original, TResult2 = never>(
        onfulfilled?: ((value: Original) => TResult1 | PromiseLike<TResult1>) | null | undefined,
        onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined
    );
}

export interface LikeInterface extends PromiseLike<Original> {}

// Prisma has a base promise type just like this
export interface WithProperty extends Promise<Original> {
    [Symbol.toStringTag]: "WithProperty";
}

I'm open to PR it if you want.

@domoritz
Copy link
Member

Always open to PRs. This is not something I need for my use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants