xstate icon indicating copy to clipboard operation
xstate copied to clipboard

Bug: Typescript issues using state.matches(...)

Open BarrBozzO opened this issue 2 years ago • 1 comments

Description

state.matches() narrows typings incorrectly in particular cases mentioned below:

  1. Nested condition is always false, but typescript doesn't warn
if (state.matches(StateA)) {
    if (state.matches(StateB)) {
        
    }
}
  1. Nested conditions are valid, but ts error occurs
if (state.matches(StateA) || state.matches(StateB)) {
    if (state.matches(StateA)) {
       ....   
    }
}

Expected result

  1. Expect to see TS error in nested condition as it is always false
if (state.matches(StateA)) {
    if (state.matches(StateB)) {
        
    }
}
  1. 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

  1. NO TS error
if (state.matches(StateA)) {
    if (state.matches(StateB)) {
        
    }
}
  1. 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

BarrBozzO avatar Jul 12 '22 06:07 BarrBozzO

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

davidkpiano avatar Jul 13 '22 06:07 davidkpiano

Being worked on in #3940

davidkpiano avatar Apr 14 '23 03:04 davidkpiano

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.

Andarist avatar Nov 29 '23 15:11 Andarist