Skip to content

Eliminate circular reference error on type T = Record<string, string | T> #46846

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

Closed
jedwards1211 opened this issue Nov 18, 2021 · 8 comments
Closed

Comments

@jedwards1211
Copy link

jedwards1211 commented Nov 18, 2021

Bug Report

TS should accept type T = Record<string, string | T> instead of flagging a circular reference error. This is self-evidently a valid and well-defined type and any arguments to the contrary are fundamentally incorrect.

The equivalent type in Flow works exactly as expected: https://flow.org/try/#0C4TwDgpgBAKlC8UDeBtAzsATgSwHYHMBdALigxwKgB9YBfAKHoGMB7XDKAMxZdLkST0oUAIalBw4QCNSAchGyANEMlNxKyVAAmcgMxKNUBsIYNmbDlJGY+CZCrH3NMqPIOa1Tzdr3vvEUgBGZU1jI3ozVnZgKCsAL1sBB3VnOQUQ1RTvHVd9DM0AqBRCfPCTCKA

🔎 Search Terms

🕗 Version & Regression Information

Seems to be any version of TS 4, tested with 4.4.4

⏯ Playground Link

https://www.typescriptlang.org/play?#code/C4TwDgpgBAKlC8UBKEDGB7ATgEwDwGdhMBLAOwHMAaKQkiqAH1gD4AoIA

💻 Code

type T = Record<string, string | T>

🙁 Actual behavior

Type alias 'T' circularly references itself.

🙂 Expected behavior

No errors

@jcalz
Copy link
Contributor

jcalz commented Nov 18, 2021

Duplicate of #41164.

Looks like you forgot to fill out the "search terms" section. This is used to show that you have searched for existing issues before opening a new one and also to allow future potential issue-filers to find your issue before opening theirs.

As an aside, I'll have to remember to use "any arguments to the contrary are fundamentally incorrect" from now on, as it evidently renders claims unassailable.

@fatcerberus
Copy link

fatcerberus commented Nov 18, 2021

Workaround:

type T = { [key: string]: string | T };

@jedwards1211
Copy link
Author

jedwards1211 commented Nov 18, 2021

@jcalz I say that because I find this issue so annoying that I wish to express utter disrespect for any counterarguments in advance

Things like this often tend to get closed as by design, I'm saying I consider the design itself a problem and ask for it to be changed

@jcalz
Copy link
Contributor

jcalz commented Nov 18, 2021

Preemptive disrespect is quite an opening move!

@fatcerberus
Copy link

The counterargument is not "by design" but "design limitation". See #41164 (comment).

@jedwards1211
Copy link
Author

jedwards1211 commented Nov 18, 2021

@jcalz not supporting natural recursion is also quite a bold design decision 😉

@jedwards1211
Copy link
Author

jedwards1211 commented Nov 18, 2021

@fatcerberus I'm failing to understand what exactly "generic instantiation is deferred" means in the context of this case, or what that specifically means about why supporting type T = Record<string, string | T> is/should be theoretically impossible.

For example the following type seems like it would have problems related to generic instantiation, yet it works:

type Stuff<T> = {[x: string]: T | Stuff<T>}

const foo: Stuff<number> = {
  a: {
    b: {d: 2}
  }
}

Whatever the supposed design limitations are, the observed behavior from a user perspective seems so illogical that I feel extremely skeptical of the reasoning behind the design limitations.

It gives me the hunch that a better design is possible that lacks these unexpected errors but doesn't have any other shortcomings that ostensibly justify the design limitations.

@jedwards1211
Copy link
Author

closing as duplicate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants