You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Type alias name (union) is not preserved when using index access/lookup types #32287
If I hover over MyObject, I see { value: 1 | 2 | 3; }.
I would expect the same behaviour as we see in my first example ({ value: MyUnion; }). The name of the type alias, MyUnion, should be preserved and its usage/reference inside of MyObject should be shown.
To give some context on my real world use case for this: I am using Unionize to create tagged unions (to avoid boilerplate for constructors, matchers, and type predicates). However, because of the issue described above, the types become very difficult to inspect/read: pelotom/unionize#60.
Under the hood, Unionize does something like this:
The fact that any type alias at all shows up is due to trickery and the limitations of that trickery are apparent in these examples.
The trick is that if the very first time we make a type it's because it's initializing a type alias, then future displays of that type use the alias name. This is a desirable heuristic because you don't want some rando .d.ts file to say
typeAcrobaticBackCompatKey=string|number|boolean;
and then have your function
functionfn(stringish: string|number|boolean){}
display back as
fn(stringish: AcrobaticBackCompatKey)
which you didn't write.
In this example, it seems the type 1 | 2 | 3 got created before it got assigned to the type alias, preventing it from being the "given name" for 1 | 2 | 3.
"Why not just make type aliases be a named pointer to the underlying type?"
Nothing's impossible, but this has some performance impacts that aren't immediately obvious. For example
In this example, the assignments can be detected to be correct almost "for free" because their types are literally the same object - there's no way to tell q and v apart. If we have to keep type aliases around all the time, then this operation becomes a lot more expensive.
So it's a trade-off and we'd have to figure out ways to make it not as expensive as it might be, or someone can maybe propose tweaks to our trickery that would make things more palatable while still not messing up existing type display too badly.
I've never dug into the compiler source, but I have an idea: Keep one type object around for typechecking, and another separate object for diagnostic reporting (only if different than the first).
So for Ryan's example, the AST for q and v might look something like this:
type is still the literally the same object, but prettyType is different and would be used when reporting errors. This would probably increase memory footprint a bit, but shouldn't noticeably increase typechecking time. For any declaration where type aliases aren't involved or the distinction isn't helpful, prettyType can be set to null, and reporting would fall back to the actual type. This would hopefully keep memory issues in check.
Of course I'm just this random guy and the devil is always in the details.
changed the title [-]Type alias name is not preserved when using index access/lookup types[/-][+]Type alias name (union) is not preserved when using index access/lookup types[/+]on Jan 5, 2021
Oliver Joseph Ash (@OliverJAsh) this has changed between 3.9.0-dev.20200330 and 3.9.0-dev.20200402. It's very likely that the change was introduced in #37444 and some tests there suggest that (like this one). So I would classify this as an intentional change :) The issue can be closed
Activity
MartinJohns commentedon Jul 8, 2019
Duplicate of #31940.
OliverJAsh commentedon Jul 8, 2019
This issue seems more specific than #31940, so not sure it's a duplicate, but the general idea is the same.
RyanCavanaugh commentedon Jul 8, 2019
The fact that any type alias at all shows up is due to trickery and the limitations of that trickery are apparent in these examples.
The trick is that if the very first time we make a type it's because it's initializing a type alias, then future displays of that type use the alias name. This is a desirable heuristic because you don't want some rando .d.ts file to say
and then have your function
display back as
which you didn't write.
In this example, it seems the type
1 | 2 | 3got created before it got assigned to the type alias, preventing it from being the "given name" for1 | 2 | 3."Why not just make type aliases be a named pointer to the underlying type?"
Nothing's impossible, but this has some performance impacts that aren't immediately obvious. For example
In this example, the assignments can be detected to be correct almost "for free" because their types are literally the same object - there's no way to tell
qandvapart. If we have to keep type aliases around all the time, then this operation becomes a lot more expensive.So it's a trade-off and we'd have to figure out ways to make it not as expensive as it might be, or someone can maybe propose tweaks to our trickery that would make things more palatable while still not messing up existing type display too badly.
OliverJAsh commentedon Jul 9, 2019
Thank you for the explanation. Unfortunately I don't have any ideas how you can resolve this.
whatisaphone commentedon Sep 18, 2019
I've never dug into the compiler source, but I have an idea: Keep one type object around for typechecking, and another separate object for diagnostic reporting (only if different than the first).
So for Ryan's example, the AST for
qandvmight look something like this:typeis still the literally the same object, butprettyTypeis different and would be used when reporting errors. This would probably increase memory footprint a bit, but shouldn't noticeably increase typechecking time. For any declaration where type aliases aren't involved or the distinction isn't helpful,prettyTypecan be set tonull, and reporting would fall back to the actualtype. This would hopefully keep memory issues in check.Of course I'm just this random guy and the devil is always in the details.
OliverJAsh commentedon Dec 30, 2020
This seems to have been fixed. Do we know what changed cause this? Was it intentional?
[-]Type alias name is not preserved when using index access/lookup types[/-][+]Type alias name (union) is not preserved when using index access/lookup types[/+]Andarist commentedon Feb 13, 2023
Oliver Joseph Ash (@OliverJAsh) this has changed between
3.9.0-dev.20200330and3.9.0-dev.20200402. It's very likely that the change was introduced in #37444 and some tests there suggest that (like this one). So I would classify this as an intentional change :) The issue can be closedFlatten indexed-access types in dist output, add ExpansionCard/Expans…