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

Type alias circularly references itself #61443

Open
aryan-mehrabi opened this issue Mar 18, 2025 Β· 6 comments
Open

Type alias circularly references itself #61443

aryan-mehrabi opened this issue Mar 18, 2025 Β· 6 comments
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Milestone

Comments

@aryan-mehrabi
Copy link

πŸ”Ž Search Terms

circular reference, generic, error TS2456, recursive

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about circular reference

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.8.2#code/C4TwDgpgBAYg9nAKuaBeKBvAsAKClAMwQH4AuKAIwQBsIBDAOwG5cBfFnXUSKAIToDOEAKK0AthAbAAPIgB8UdPCQooAMky58AYwAWAS2oATAE6TyAYQCuA4HDGiIEqQG0Auh3zcI5RB3a4XKrWtvaOzsCKfIIi4pIyAOS6AIwJchxAA

πŸ’» Code

type FooType = {
  foo?: boolean;
};

type BaseElement<T> = FooType & {
  children: CustomElement[];
  type: T;
};

type CustomElement = BaseElement<'h1'>;

πŸ™ Actual behavior

When defining a recursive type structure using a generic type, TypeScript incorrectly reports a Type alias 'CustomElement' circularly references itself.(2456) error, even though the type should be resolvable.
It gets weird when you move type: T; line above the children: CustomElement[]; and the error disappears. Also removing FooType will resolve the issue.

πŸ™‚ Expected behavior

In the first place the code should not throw any errors, in the second place the behavior should not change by reordering records of a type.

Additional information about the issue

No response

@nmain
Copy link

nmain commented Mar 19, 2025

No responses so far, so I'll take a stab at this. The first thing you'll want to read is this FAQ entry: https://github.com/microsoft/TypeScript/wiki/FAQ#circularity-errors-may-occur-in-the-presence-of-circularities.

The type you've given here is obviously circular. And while the Typescript compiler can resolve circularities in many simple cases, so that useful things like recursive tree types can exist, it's not guaranteed to be able to do that in every arbitrary case of intersections, generic instantiations, and other manipulations. It's also not a defect just because certain rearrangements make the type resolve (that's straight out of the FAQ). And this one is not a regression since it's been like that since at least 3.3.

I can't say for sure whether the Typescript team is interested in changing the behavior in this case, but all signs point to it being a low priority at best.

@aryan-mehrabi
Copy link
Author

Hi @nmain,

So this is actually a bug but Typescript team has no plan to fix it any soon?

@snarbles2
Copy link

It's not a bug per se, and it's probably virtually impossible to come up with a solution that will accept any definition that can be construed as valid. That said, with circularities, you can usually rejigger them until the error goes away. For instance, this seems to work fine:

type FooType = {
  foo?: boolean;
};

interface BaseElement<T> extends FooType {
  children: CustomElement[];
  type: T;
};

type CustomElement = BaseElement<'h1'>;

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases labels Mar 19, 2025
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Mar 19, 2025
@aryan-mehrabi
Copy link
Author

@snarbles2 I'm aware of ways to fix this issue as I mentioned in the issue:

It gets weird when you move type: T; line above the children: CustomElement[]; and the error disappears.

I think something should be implemented to make circular references behave more predictably to save developers from wasting time. I'm also willing to help fix this issue (at least the rearrangement issue).

@snarbles2
Copy link

Ah, sorry. Reading comprehension fail.

@RyanCavanaugh
Copy link
Member

I think something should be implemented to make circular references behave more predictably to save developers from wasting time.

"more predictable" here generally means "error more", we already want to error less. PRs welcomed for sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Projects
None yet
Development

No branches or pull requests

4 participants