-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
fix(NODE-3668): compile error with OptionalId on TS 4.5 beta #3004
Conversation
Typescript 4.5 is better at checking certain complicated types than before. Previously, it missed an error in mongo_types.ts in the use of SetFields and OptionalId. SetFields passes an unconstrained type parameter, TSchema, to OptionalId, which does have a constraint: ```ts export type OptionalId<TSchema extends { _id?: any }> = ... ``` Because the type was so complex, Typescript missed this before 4.5. Looking at the comments for OptionalId, I believe the intent is to add `_id` to *any* type, not just ones that already have an `_id` field. So I moved the constraint into a conditional type instead.
Hi @sandersn thanks so much for helping us out here! The ternary in
I'm seeing some issues with our type tests that I'm going to investigate further soon, we're using tsd which I think is tied to TS version so it might not be actually testing these changes with the beta. |
The only difference I can see between your prose and the code is that the check |
I have a playground link here, while this may fix the crash upon import for SetFields it has broken the use case number 3. I'm trying to come up with a fix but if you see something here let me know. 🙂 |
Reading through that, is there a reason line 25 has |
Playing with the link you sent, I'm pretty sure that the intention is to add an optional export type OptionalId<TSchema> = TSchema extends { _id?: any }
? ObjectId extends TSchema['_id'] // a Schema with ObjectId _id type or "any" or "indexed type" provided
? EnhancedOmit<TSchema, '_id'> & { _id?: InferIdType<TSchema> } // a Schema provided but _id type is not ObjectId
: EnhancedOmit<TSchema, '_id'> & { _id: InferIdType<TSchema> }
: EnhancedOmit<TSchema, '_id'> & { _id?: InferIdType<TSchema> }; // TODO(NODE-3285): Improve type readability I'm pretty sure this worked by mistake before when you pass an object without Edit: for comparison, here is the pre-PR version: export type OptionalId<TSchema> = TSchema extends { _id?: any }
? ObjectId extends TSchema['_id'] // a Schema with ObjectId _id type or "any" or "indexed type" provided
? EnhancedOmit<TSchema, '_id'> & { _id?: InferIdType<TSchema> } // a Schema provided but _id type is not ObjectId
: WithId<TSchema>
: WithId<TSchema>; // TODO(NODE-3285): Improve type readability |
I pushed a commit to the PR that makes _id optional for case (3). |
I was able to test locally with tsd using TS 4.4 and 4.5 and it passes 🚀 Also thanks @PaulEndri for takin a look as well! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks everyone!
Typescript 4.5 is better at checking certain complicated types than before. Previously, it missed an error in mongo_types.ts in the use of SetFields and OptionalId.
SetFields passes an unconstrained type parameter, TSchema, to OptionalId, which does have a constraint:
Because the type was so complex, Typescript missed this before 4.5.
Looking at the comments for OptionalId, I believe the intent is to add
_id
to any type, not just ones that already have an_id
field. So I moved the constraint into a conditional type instead.Fixes https://jira.mongodb.org/browse/NODE-3668?jql=project%20%3D%20NODE%20AND%20resolution%20%3D%20Unresolved%20AND%20text%20~%20%22typescript%22%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC
Description
What changed?
Types in mongo_types.ts