Repository navigation
Circularities Only Blocked Sometimes #37426
Description
Activity
Sorry if I hijack this issue, but I truly am not sure whether what I'm also experiencing somehow has a similar root cause to the OP (similar issue search took me here). Harry Solovay (@harrysolovay) perhaps you could see if the behavior described below contributes to/is related to your issue in any way?
The issue that I've come across is that if a generic interface (
GenericBox) is directly part of a type alias (Foo), that type alias can use itself as generic argument to the generic interface. However, if the generic interface is then used as a part of a generic type alias (Bar), another type alias (UnionOfBar) sending itself as generic argument into this generic type will result in a circular reference error. (live)interface GenericBox<T> { value: T; } type Foo = GenericBox<Foo> | string; // OK type Bar<T> = GenericBox<T>; type UnionOfBar = Bar<UnionOfBar> | string; // Circular reference error
harrysolovay commented
on Mar 17, 2020 AuthorMore actionssoul-codes circularities are allowed in tuples, of which
UnionOfBaris not. In tuples, it's possible to resolve the signature of the tuple to type-check its child elements, which might share their parent's signature. In the situation you describe,UnionOfBar's signature is unclear––it describes itself. Might I ask what is your use case? There's likely a better way to describe your data.Also––if you wish to ask––please do so on StackOverflow, and link to your question from here. This forum is really only for bugs/potential bugs/feature requests.
RyanCavanaugh commented
on Mar 17, 2020 MemberMore actionsThis might be fixed by #37423 ; it's worth checking.
If not, this is kind of like how the police only sometimes pull you over for speeding. "Fixing" this probably won't be in the direction you want 😉
If you can narrow this down to a super simple example we could advise further
Reacted by Daniel Rosenwasser- addedNeeds InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.
on Mar 17, 2020 Harry Solovay (@harrysolovay) understood. I just wondered if our issues were in fact the same and perhaps, as Ryan has requested, yours could simplify to mine. It seems like it is rather a misunderstanding of how circularity is supposed to work on my side which led me to mistake it as a bug/issue. I will proceed to SO accordingly. Sorry to pollute this issue folks!
Reacted by Harry Solovayharrysolovay commented
on Mar 22, 2020 AuthorMore actionsI was definitely speeding 😂
I managed to implement the desired type-mapping thanks to a StackOverflow answer provided by the creator of Punchcard, a serverless DX, which I encourage all to check out!
One of the monorepo's packages, "Shapes" (like "Codecs"), is used to map between the representations of different services while enforcing type-safety. Really, really cool. Anyone who's trying to achieve recursive mapping between types should check it out.
Reacted by sam
TypeScript Version: 3.8.2
Search Terms: circular, type, mapping, tuple, corresponding, signature
This builds off of the issue I just submitted (tagged as a bug).
In summary, I'm trying to create a virtual type system.
I define the available types:
I create a
Codectype:And I create a utility type, which can be used to unwrap / gather the corresponding type.
Surely enough, it works for
Codec<Type.Int>:It works for
Codec<Type.Boolean>:And it works for
Codec<Type.List>:TypeScript Playground of the example up to this point
We see
Decodeworks, even though it's self-referencing. There's no cycle-related error––presumably because of the use of tuples, which seem somewhat cycle-friendly since 3.7. Now let's add another type:enum Type { Boolean = "Boolean", Int = "Int", List = "List", + Union = "Union", }We modify the
Codectype to support multiple array of typeCodec(the types to unite):And we update the definition of
AnyCodec:Let's instantiate this type:
And let's create and use the corresponding
DecodeUnionutility:TypeScript Playground of this example, continued up to this point
The utility works!
UnionOfIntAndBooleanDecodedis inferred as being of typenumber | boolean. Last but not least, let's integrateDecodeUnioninto the more generalDecodeutility type.This is where we run into trouble:
TypeScript Playground, with the error-producing code
While the prior self-reference did not result in a circularity error, this one does:
Type alias 'Decode' circularly references itself.Is there a workaround? Could this be related to the aforementioned issue?
I know I've said it many times, but I truly mean it every time when I say: your help is greatly appreciated & thank you!!!