Can anyone explain this behavior in Typescript?

Viewed 62

This seems like a bug to me, but before I report it to the Typescript repository I thought it would be good to see if there was an explanation for it I am not aware of, here's the playground.

As you can see in the playground, seemingly identical types throw an error in slightly varied implementations. Is there any explanation for the discrepancy?

Take this interface definition from the playground:

interface Test {
  fooBarBaz(bar?: false): Promise<Baz>;
  fooBarBaz(bar: true): Promise<Bar>;
}

If I then instantiate an object of type Test in the following way:

const test: Test = {
  async fooBarBaz(bar?: boolean): Promise<BarBaz> {
    if (bar) {
      return {
        bar: 'baz',
      }
    }

    return {
      bar: 'baz',
      baz: [{ foo: 'bar' }],
    }
  }
}

There's an error from the compiler:

Type '(bar?: boolean | undefined) => Promise<BarBaz>' is not assignable to type '{ (bar?: false | undefined): Promise<Baz>; (bar: true): Promise<Bar>; }'.
  Type 'Promise<BarBaz>' is not assignable to type 'Promise<Baz>'.
    Type 'BarBaz' is not assignable to type 'Baz'.
      Type 'Bar' is not assignable to type 'Baz'.
        Types of property 'baz' are incompatible.
          Type '{ foo: string; }[]' is not assignable to type 'undefined'.(2322)

However, if I declare a function definition like this:

async function fooBarBaz(bar?: false): Promise<Baz>;
async function fooBarBaz(bar: true): Promise<Bar>;
async function fooBarBaz(bar?: boolean): Promise<BarBaz> {
  if (bar) {
    return {
      bar: 'baz',
    }
  }

  return {
    bar: 'baz',
    baz: [{ foo: 'bar' }],
  }
}

and then instantiate an object of the same type Test in the following manner:

const test2: Test = {
  fooBarBaz,
}

The compiler does not complain at all.

0 Answers
Related