Closed avin-kavish closed 1 year ago
I'm getting some inconsistent behaviours with how it handles container types. For example, using the above type,
class Foo {}
type ManagedReference<Other> = Other & Ref<any, Other>
type X = ManagedReference<any> // resolves to any
type Y = ManagedReference<unknown> // resolves to Ref<any, unknown>
type Z = ManagedReference<Foo> // resolves to intersection with Foo & Ref<any, Foo>
type V = ManagedReference<Foo | null> // same type as above but empty name & fullName, I think this is a bug
When it resolved to any, it's not visible whether a container was used. I think we should be capturing the type the user has used, not the final simplified type.
That simplification is what TypeScript does, that's how the type
aliases works. It's just "virtual" placeholder; it's not a real type. Type alias is direct type reference or alias/placeholder for some unions and/or intersections. That's why container types should not have name nor fullName, never. U should not try to compare containers directly IMHO. You can end up with one container which will be union of two other containers eg. intersections. type A = (B & C) | (D & E)
Maybe the top level container will have a name, but those inner containers will not, they have no name, because they are not aliased.
Eg. type T = any & Ref<any, any>
.
I'm able to get information about that alias by reading its declaration (traversing the AST) but that's complicated. I would have to handle all possible declarations. That's why Record, Omit etc. were not working for a long time. I removed manual reading and now I just ask TS what type it is.
But I can change a behavior around types
a little. I can introduce new kind Alias
. It will have name and fullName but it will still resolve into final simplified type. It will be like Container
kind but you will know that it is specific type
alias with name and fullName.
Alias
kind should work for my use case but if you want to keep original typescript behaviour, even a way to check the "deep equality" of the type could work. I'm not really interested in name of the type but it's just knowing that they are exactly equal, (not structurally). Side-effect of fullname not being there is is
comparison doesn't work.
In containers, then equality would have to be checked recursively descending into the types
property. And by equality I mean, exact class is used. (even though ts considers classes structurally assignable, instanceof checks fail). And there would have to be a similar rule set for other types.
P.S. when doing Alias
there will be a generic case to consider. eg, my type above type ManagedReference<Other>
Fixed in v1. Not in the current version.