-
Notifications
You must be signed in to change notification settings - Fork 641
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 for empty models / models with all properties set to optional being able to take any value in TypeScript #1269
Conversation
/** @hidden */ | ||
export type ExtractCFromProps<P extends ModelProperties> = { [k in keyof P]: P[k]["CreationType"] } | ||
|
||
/** @hidden */ | ||
export type ModelCreationType<PC> = { [P in DefinablePropsNames<PC>]: PC[P] } & Partial<PC> | ||
export type KeylessToEmptyObject<O> = keyof O extends never ? EmptyObject : O |
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.
keyof O extends never
💯
While it works I'm going to mark it as WIP since merging this would make the 50 iterations error from TS3.4 appear again :/ Hopefully this new feature from TS (microsoft/TypeScript#30637) means what I think it means and then it might even resolve by itself. Anyway it only exhibits in two cases
|
Ok, i just checked with the next TSC and it doesn't appear to mean what I think :-/ (unless it wasn't still there in the nightly build) |
If it is troublesome with TS 3.4, I would wait a bit before merging this
…On Tue, Apr 30, 2019 at 8:08 PM Javier Gonzalez ***@***.***> wrote:
While it works I'm going to mark it as WIP since merging this would make
the 50 iterations error from TS3.4 appear again :/
Hopefully this new feature from TS (microsoft/TypeScript#30637
<microsoft/TypeScript#30637>) means what I think
it means and then it might even resolve by itself.
Anyway it only exhibits in two cases
1. when the model has no props the creation/snapshot/instance types
accept anything
2. when all model props are optional then creation accepts arrays and
numbers, but not wrong objects, while the other types seem ok
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#1269 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAN4NBB2JQ5X7GTOUN5PVHTPTCDKBANCNFSM4HJFZUBQ>
.
|
managed to reduce the number of iterations to 46, but still too high I think. Maybe it would be better to change types.model typings so it cannot take an empty object as props? |
Sounds as a good idea anyway
That is actually quite a common case I presume 😢 |
I'm not sure if the issue is big enough to warrant the additional complexity in the typings. Ok to close this one? |
I'd like to try some ideas I had to reduce the number of types nesting before giving up on this one. |
np!
…On Fri, Jul 19, 2019 at 9:36 PM Javier Gonzalez ***@***.***> wrote:
I'd like to try some ideas I had to reduce the number of types nesting
before giving up on this one.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#1269?email_source=notifications&email_token=AAN4NBGIKOYCTQIUB5TDZVDQAIJTJA5CNFSM4HJFZUB2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2MRZLY#issuecomment-513350831>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAN4NBAO3TSRKOSDGZ5OF7LQAIJTJANCNFSM4HJFZUBQ>
.
|
I still haven't got to proper upgrading to 3.5 due to #1341, but I am expecting this is gonna bite me too. I do have a couple of models with all props optional. I wonder what's wrong with the PR? Does it work with that? Doesn't seem to be overly complicated, so I am not sure why to abandon it. |
The problem has to do with a limit (added in TS 3.4 I think?) on how deep conditional types can go, which is 50 levels deep. Some medium-big projects where reaching that limit and that got fixed, but this PR adds some more levels and makes it go over 50 again, thus making these medium-big projects un-compilable. I was just thinking of trying to leverage interfaces as "cached" types to reduce nesting, something like
rather than directly
something like that (although it is an oversimplification), but I still have to check if that actually reduces nesting |
@mweststrate Ok I found a better way to fix it and not increase the depth levels at all, basically by always '&' a non empty object like { [someSymbol]?: any } Also while at it updated the dev deps, which includes a nice update to the typedocs markdown plugin, which should result in a bit better looking autogenerated docs |
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
@xaviergonz We got some approvals here. I suppose you can resolve conflicts and merge? :) |
Should be fixed. |
@mweststrate since the fix for flow typings require ts3.6, is it ok to merge? |
I think it is OK if it is mentioned in the changelog, and at least a minor release |
Since mobxjs#1269 marked `castFlowReturn` as deprecated, it shouldn't be mentioned as needed in the docs.
This was introduced in mobxjs#1269 to prevent passing in any object to a model type that had no props. Although this works great, some people have found it harder to work with because now `keyof typeof MyModelType` now has this extra key they have to deal with. One could intersect that type with `string`, but it's unfortunate that users have to do this. Instead, we use `Record<string, never>` which can only be represented by an empty object literal. Snapshot preprocessors also had to be tweaked because they can emit properties that aren't known to them in the case of composition with other types.
This was introduced in mobxjs#1269 to prevent passing in any object to a model type that had no props. Although this works great, some people have found it harder to work with because now `keyof typeof MyModelType` now has this extra key they have to deal with. One could intersect that type with `string`, but it's unfortunate that users have to do this. Instead, we use `Record<string, never>` which can only be represented by an empty object literal. Snapshot preprocessors also had to be tweaked because they can emit properties that aren't known to them in the case of composition with other types.
* Eliminate `NonEmptyObject` This was introduced in #1269 to prevent passing in any object to a model type that had no props. Although this works great, some people have found it harder to work with because now `keyof typeof MyModelType` now has this extra key they have to deal with. One could intersect that type with `string`, but it's unfortunate that users have to do this. Instead, we use `Record<string, never>` which can only be represented by an empty object literal. Snapshot preprocessors also had to be tweaked because they can emit properties that aren't known to them in the case of composition with other types. * Don't allow symbols in input snapshots for models with no props
* Eliminate `NonEmptyObject` This was introduced in #1269 to prevent passing in any object to a model type that had no props. Although this works great, some people have found it harder to work with because now `keyof typeof MyModelType` now has this extra key they have to deal with. One could intersect that type with `string`, but it's unfortunate that users have to do this. Instead, we use `Record<string, never>` which can only be represented by an empty object literal. Snapshot preprocessors also had to be tweaked because they can emit properties that aren't known to them in the case of composition with other types. * Don't allow symbols in input snapshots for models with no props
Apparently, in TS this is valid
which means that for empty objects / objects where all properties were optional any value was valid
This PR fixes this by turning empty objects into an object like
which doesn't have any properties in common with array, classes, etc.
Also updates some dev deps and fixes some typos