Skip to content
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 states coming from model.createMachine resulting in contexts of type any after type refinements #2436

Merged
merged 4 commits into from
Jul 20, 2021

Conversation

Andarist
Copy link
Member

fixes #2423

Note that this PR contains 2 separate fixes for the reported issue. Any of them could be removed and the reported issue would still be fixed. I will comment on each one "inline"

…g in contexts of type `any` after type refinements
'xstate': patch
---

Fixed an issue with states coming from `model.createMachine` resulting in contexts of type `any` after type refinements such as here:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm super tired already and I have a feeling that I've written some hard-to-understand gibberish here. If you have any ideas on how I could rephrase this I would appreciate the help.

Copy link
Contributor

@johtso johtso Jul 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like?

Fixed issue where, when using model.createMachine, state context was incorrectly inferred to be any after refinement with .matches(..), for example:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for taking a stab at rewording this! Would you like to prepare this as a PR suggestion that I could just commit with a button click? The change would also be contributed to you that way which is nice :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Fixed an issue with states coming from `model.createMachine` resulting in contexts of type `any` after type refinements such as here:
Fixed an issue where, when using `model.createMachine`, state context was incorrectly inferred as `any` after refinement with `.matches(...)`, such as in here:

Using @johtso's suggestion

@@ -32,7 +32,7 @@ export interface Model<
createMachine: (
config: MachineConfig<TContext, any, TEvent>,
implementations?: Partial<MachineOptions<TContext, TEvent>>
) => StateMachine<TContext, any, TEvent, any>;
) => StateMachine<TContext, any, TEvent>;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This resulted in the default type not being chosen here:

TTypestate extends Typestate<TContext> = { value: any; context: TContext }

which in turn resulted in any being selected here:
? TTypestate

The alternative fix here would be to use the default type explicitly here. It would be more explicit but it's probably not worth it at the moment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for digging into this and fixing it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem. That's my job 😍

? TTypestate
: never
: never)['context'],
Equals<TTypestate, any> extends 1
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not strictly necessary because the other. simple, fix already fixes the reported issue.

This seems a little bit heavy (adding more local complexity here) but handles "more" scenarios. I feel like if the TTypestate is not configured then the most sensible approach is to prefer using TContext. However, this still doesn't handle unknown and never and if we do this then it would probably be the most sensible approach for all of those special types.

I think I'm leaning towards removing this part of the fix for the time being. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let's remove this and revisit later 👍

Comment on lines 22 to 26
type Equals<A1 extends any, A2 extends any> = (<A>() => A extends A2
? 1
: 0) extends <A>() => A extends A1 ? 1 : 0
? 1
: 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😳

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be true or false instead of 1 or 0?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could. It's just taken from here and this type collection is using the 1/0 pattern in all its types.

I'm still wondering if we should use this though, see the comment here: #2436 (comment)

@Andarist Andarist merged commit 800b631 into main Jul 20, 2021
@github-actions github-actions bot mentioned this pull request Jul 20, 2021
@Andarist Andarist deleted the fix/model-create-machine-typestates branch March 22, 2023 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Context type becomes any after matches conditional
4 participants