xstate
xstate copied to clipboard
Bug: Typescript issues using state.matches(...)
Description
state.matches()
narrows typings incorrectly in particular cases mentioned below:
- Nested condition is always
false
, but typescript doesn't warn
if (state.matches(StateA)) {
if (state.matches(StateB)) {
}
}
- Nested conditions are valid, but ts error occurs
if (state.matches(StateA) || state.matches(StateB)) {
if (state.matches(StateA)) {
....
}
}
Expected result
- Expect to see TS error in nested condition as it is always
false
if (state.matches(StateA)) {
if (state.matches(StateB)) {
}
}
- Expect to see no TS error here, as it is a valid state check
if (state.matches(StateA) || state.matches(StateB)) {
if (state.matches(StateA)) {
....
}
}
Actual result
- NO TS error
if (state.matches(StateA)) {
if (state.matches(StateB)) {
}
}
- TS error: Argument type of StateA is not assignable to parameter of type 'never'.
if (state.matches(StateA) || state.matches(StateB)) {
if (state.matches(StateA)) {
....
}
}
Reproduction
https://codesandbox.io/s/reverent-haibt-wsyv9h?file=/src/index.tsx
Additional context
@xstate/react: 3.0.0 xstate: 4.32.1 Typescript: 4.7.4
This is a very difficult TypeScript problem to solve, and we're still thinking about ways to improve typestates for v5, as the current way is unsound. cc. @Andarist
Being worked on in #3940
I don't think we want to implement this right now at the TypeScript level. We might provide this as part of additional linting rules in the future though.