microsoft/typescript-go

New error when inferring return type from similar object types with promises

Opened this issue · 1 comments

Steps to reproduce

function getInfo(): Promise<{
    id?: string;
    history?: string[];
}> {
    return Promise.resolve().then(() => {
        if (Math.random() > 0.5) {
            return Promise.resolve().then(() => {
                return {
                    id: "1",
                    history: ["1"],
                };
            });
        } else {
            return Promise.resolve({
                history:["1"],
            });
        }
    });
}

Playground Link

Behavior with typescript@5.8

The code above passes type checking.

Behavior with tsgo

We get an error saying:

src/index.ts:5:35 - error TS2345: Argument of type '() => Promise<{ history: string[]; }> | Promise<{ id?: string | undefined; history?: string[] | undefined; } | { id: string; history: string[]; }>' is not assignable to parameter of type '(value: void) => PromiseLike<{ history: string[]; }> | { history: string[]; }'.
  Type 'Promise<{ history: string[]; }> | Promise<{ id?: string | undefined; history?: string[] | undefined; } | { id: string; history: string[]; }>' is not assignable to type 'PromiseLike<{ history: string[]; }> | { history: string[]; }'.
    Type 'Promise<{ id?: string | undefined; history?: string[] | undefined; } | { id: string; history: string[]; }>' is not assignable to type 'PromiseLike<{ history: string[]; }> | { history: string[]; }'.
      Type 'Promise<{ id?: string | undefined; history?: string[] | undefined; } | { id: string; history: string[]; }>' is not assignable to type 'PromiseLike<{ history: string[]; }>'.
        Types of property 'then' are incompatible.
          Type '<TResult1 = { id?: string | undefined; history?: string[] | undefined; } | { id: string; history: string[]; }, TResult2 = never>(onfulfilled?: ((value: { id?: string | undefined; history?: string[] | undefined; } | { id: string; history: string[]; }) => TResult1 | PromiseLike<...>) | null | undefined, onrejected?: (...' is not assignable to type '<TResult1 = { history: string[]; }, TResult2 = never>(onfulfilled?: ((value: { history: string[]; }) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | null | undefined) => PromiseLike<...>'.
            Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
              Types of parameters 'value' and 'value' are incompatible.
                Type '{ id?: string | undefined; history?: string[] | undefined; } | { id: string; history: string[]; }' is not assignable to type '{ history: string[]; }'.
                  Type '{ id?: string | undefined; history?: string[] | undefined; }' is not assignable to type '{ history: string[]; }'.
                    Types of property 'history' are incompatible.
                      Type 'string[] | undefined' is not assignable to type 'string[]'.
                        Type 'undefined' is not assignable to type 'string[]'.

This is type ordering again. The equivalent code (swapping the true and false branches of the if) errors in 5.8 (with the exact same error message):

function getInfo(): Promise<{
    id?: string;
    history?: string[];
}> {
    return Promise.resolve().then(() => {
        if (Math.random() > 0.5) {
            return Promise.resolve({
                history:["1"],
            });
        } else {
            return Promise.resolve().then(() => {
                return {
                    id: "1",
                    history: ["1"],
                };
            });
        }
    });
}