I have two types that should be semantically identical. Why is one resulting in an error while the other one gets accepted?

49 views Asked by At

Take the following TypeScript code (you can see it live at https://tsplay.dev/w1GYAm):

type Graph<T=any> = {
    A?: T,
    B?: T,
    C?: T,
};

type X<T extends Graph> = T['B'] | T['C'] | number;
type Y<T extends Graph> = [ T['A'], T['A'] ];

type Y1<T extends Graph> = [ T['A'], T['A'] ] | T['C'];
type Y2<T extends Graph> = Y<T> | T['C'];

type G1 = {
  A: X<G1>,
  B: Y1<G1>,
  C: number,
};

type G2 = {
  A: X<G2>,
  B: Y2<G2>,
  C: number,
};

Y1 and Y2 should be semantically identical, thus G1 and G2 should be identical too.

However I'm getting an error on G1, but no error in G2:

'A' is referenced directly or indirectly in its own type annotation.
'B' is referenced directly or indirectly in its own type annotation.

The error seems persistent: removing either G1 or G2 doesn't change the state of the other.

Why am I getting an error in G1, while G2 is accepted?

Furthermore, is this a bug in TypeScript or expected behavior? Is Typescript expected to be undecidable for cyclic/recursive stuff?

0

There are 0 answers