Skip to content

tsgo fails to report TS2769 for mutually-exclusive object overloadsΒ #63051

@r253hmdryou

Description

@r253hmdryou

πŸ”Ž Search Terms

  • TS2769
  • exclusive
  • overload
  • tsgo
  • mutually exclusive

πŸ•— Version & Regression Information

This is not a regression.

The behavior has been observed in current versions of tsgo.
tsc has consistently reported an error for this pattern, while tsgo has never reported one.

I tested the repro with the latest available tsgo build and the issue still reproduces.

This does not appear to be a recently introduced change, but rather a missing or incomplete diagnostic in tsgo’s overload resolution logic.

⏯ Playground Link

N/A β€” this repro requires tsgo; TypeScript Playground runs tsc.

πŸ’» Code

type A = { a: { x: 1 }; b?: never };
type B = { b: { y: 1 }; a?: never };

export function defineFoo<const N extends string>(name: N, config: A): void;
export function defineFoo<const N extends string>(name: N, config: B): void;
export function defineFoo(name: string, config: unknown) {
  void name;
  void config;
}

// Both a and b provided (mutually exclusive).
defineFoo("foo", {
  // @ts-expect-error - a and b are mutually exclusive; provide exactly one.
  a: { x: 1 },
  b: { y: 1 }
});

πŸ™ Actual behavior

Running:

$ npm run typecheck:go
> tsgo -p tsconfig.json

produces no errors.
That means tsgo is not reporting an overload resolution failure where tsc clearly does.

πŸ™‚ Expected behavior

Running:

$ npm run typecheck

> typecheck
> tsc -p tsconfig.json

src/repro.ts:14:1 - error TS2769: No overload matches this call.
  Overload 1 of 2, '(name: "foo", config: A): void', gave the following error.
    Type '{ y: number; }' is not assignable to type 'undefined'.
  Overload 2 of 2, '(name: "foo", config: B): void', gave the following error.
    Type '{ x: number; }' is not assignable to type 'undefined'.

14 defineFoo("foo", {
   ~~~~~~~~~

  src/repro.ts:3:25
    3 type A = { a: { x: 1 }; b?: never };
                              ~
    The expected type comes from property 'b' which is declared here on type 'A'
  src/repro.ts:4:25
    4 type B = { b: { y: 1 }; a?: never };
                              ~
    The expected type comes from property 'a' which is declared here on type 'B'
  src/repro.ts:8:17
    8 export function defineFoo(name: string, config: unknown) {
                      ~~~~~~~~~
    The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.

src/repro.ts:15:3 - error TS2578: Unused '@ts-expect-error' directive.

15   // @ts-expect-error - a and b are mutually exclusive; provide exactly one.
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 2 errors in the same file, starting at: src/repro.ts:14

Additional information about the issue

This issue is distinct from microsoft/typescript-go#1088 (which concerns @ts-expect-error diagnostic placement).
Here, the core issue is that tsgo does not report an overload resolution error at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions