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
Fixed an issue with contextual type for intersection properties (take 2) #52095
base: main
Are you sure you want to change the base?
Fixed an issue with contextual type for intersection properties (take 2) #52095
Conversation
From experience with the larger TS community, I can say with some confidence that Also aren't |
One is |
@phryneas Hmm, if they behave differently then that makes this rather misleading: |
That indeed seems to be a bit misleading. The definition of type Record<K extends keyof any, T> = {
[P in K]: T;
}; |
Yeah, I was aware that was the implementation. I just thought that @matheusiacono I'm... not sure why you 👎'd my comment? That the hover tip displays an index signature when the actual type behaves differently from what's displayed is factual and not just my opinion. |
Note that this PR doesn't necessarily have to break patterns like this. It's hard to tell though - I would have to examine a concrete example, with a concrete use case in mind (contextual typing, completions, etc). As to the difference between It's helpful to check out the TS AST Viewer and the flags contained on those types (link here). Also note that their types have different IDs - which is the ultimate no answer to the question if they are the same. // flags: Object (2 ^ 19) | DefinitelyNonNullable | StructuredType | StructuredOrInstantiable | ObjectFlagsType | Narrowable | IncludesMask | NotPrimitiveUnion
// objectFlags: Anonymous (2 ^ 4) | ObjectTypeKindMask
type A = { [key: string]: number }
// flags: Object (2 ^ 19) | DefinitelyNonNullable | StructuredType | StructuredOrInstantiable | ObjectFlagsType | Narrowable | IncludesMask | NotPrimitiveUnion
// objectFlags: Mapped (2 ^ 5) | Instantiated (2 ^ 6) | CouldContainTypeVariablesComputed (2 ^ 19) | CouldContainTypeVariables (2 ^ 20) | ObjectTypeKindMask
type B = Record<string, number>
// flags: Object (2 ^ 19) | DefinitelyNonNullable | StructuredType | StructuredOrInstantiable | ObjectFlagsType | Narrowable | IncludesMask | NotPrimitiveUnion
// objectFlags: Mapped (2 ^ 5) | ObjectTypeKindMask
type C = { [K in string]: number } We might notice here that all of them have the same flags but they are all different when it comes to That being said - I can't be sure if the proposed change is how this whole fix should look like. It's a conversation starter, maybe I will have to tweak this based on the TS team feedback. |
…ections-here-we-go-again
Does this PR create an observable difference between |
@andrewbranch it creates an observable difference in getting the type of the property of a contextual type. Some of the the new test cases wouldn't infer correctly with the generic constraint of However, I'm not saying - by any means - that this is what I want to land. This whole PR is meant to restart the conversation around this since the original PR landed and got reverted later. When discussing the regression in #49307, both you and @RyanCavanaugh said that the original PR had merit and that contextual properties coming from index signatures are dubious (when a concrete property is available) and that cases like this were handled inconsistently by TS. The original PR was reverted to give you more time to think about this - it has been half a year and I just hope to revive this conversation. There are some important things to note down here - we don't need to create any observable difference between both of those. This is not required to fix what this PR is fixing. So to move this PR forward we can either:
|
For the record we already only support TS 4.2+ as of RTK 1.9. |
Your CI job just reported that the proposed solution doesn't work for you 🤣 it seems that there is more to this there than what was captured by the slimmed-down repro |
…ections-here-we-go-again
…ections-here-we-go-again
@andrewbranch @RyanCavanaugh would there be a chance to put this on 5.2 agenda since the work on that has just started? I would gladly tweak the content of this PR however you see fit - but right now it's not entirely obvious how this should behave when index signatures are involved. This probably warrants a design meeting or something. |
…m concrete props or from applicable index infos
To get the ball rolling I made some changes to this PR. I decided to treat indexed mapped type substitutions within intersections differently. Now they are intersected with either concrete property types or with applicable index info types. They are not treated as "concrete" - so they don't take precedence over applicable index info types. They are always used though, if we find any concrete property types then we intersect them with those. If we don't have any concrete property types then we find applicable index info types and we intersect with those. It is somewhat strange... but it maintains backward compatibility. |
…ections-here-we-go-again
@ahejlsberg @gabritto friendly 🏓 |
…ections-here-we-go-again
@jakebailey would u mind creating a playground for this one? |
@typescript-bot pack this |
Heya @jakebailey, I've started to run the tarball bundle task on this PR at 6d24ca8. You can monitor the build here. |
Hey @jakebailey, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running |
@typescript-bot pack this |
Heya @jakebailey, I've started to run the tarball bundle task on this PR at ea31c96. You can monitor the build here. |
Hey @jakebailey, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build and an npm module you can use via |
…ections-here-we-go-again
@ahejlsberg @gabritto friendly 🏓 |
…ections-here-we-go-again
@ahejlsberg @gabritto @RyanCavanaugh any chance that this could be considered for 5.5? It fixes one of the "Help wanted" issues - let me help you! 😉 |
fixes #48812
fixes #55150
This PR is another take on what already has been approved and merged: #48668 . It later got reverted to give time for further investigation of #49307 since that PR broke Redux Toolkit's types.
This PR adds adjusted test cases that were discovered in #49307. The minimal repro case posted by @andrewbranch was this:
I decided to treat indexed mapped type substitutions within intersections differently. Now they are intersected with either concrete property types or with applicable index info types.
They are not treated as "concrete" - so they don't take precedence over applicable index info types. They are always used though, if we find any concrete property types then we intersect them with those. If we don't have any concrete property types then we find applicable index info types and we intersect with those.
cc @andrewbranch @RyanCavanaugh @phryneas @markerikson