1

I am writing my first XState-driven app in TypeScript, with the FAST framework from Microsoft. I am getting a compile-time error on my states.loading.invoke.onDone.actions property, that looks like this:

export const questions = {
  initial: 'loading',
  states: {
    loading: {
      invoke: {
        id: 'loadQuestions',
        src: (context, event) => fetchQuestions,
        onDone: {
          target: 'asking',
          actions: assign({
            questions: (context, event: any) => event.data // this is generating an error
          })
        },
        onError: {}
      },
      tags: ['loading'],
    },
    asking: {
      always: [{
        target: '#search',
        cond: 'questionsExhausted'
      }],
      on: {
        QUESTION_ANSWERED: ''
      }
    }
  }
}

The machine looks like this:

const states = {questions, search};

const initial = 'questions';

interface EventsSearchContext  {
  questions: Question[];
}

const context = {
  questions: []
};

const config = {
  schema: {
    context: {} as EventsSearchContext
  },
  id: 'eventsSearch',
  initial,
  context,
  states
}

const eventsSearchMachine = createMachine(config);

and my search states look like this:

export const search = {
  id: 'search',
  initial: 'performingSearch',
  states: {
    performingSearch: {},
    displayingResults: {}
  }
};

Just a basic outline at the moment, but this error is being generated:

Types of property 'onDone' are incompatible.
  Type '{ target: string; actions: AssignAction<unknown, any>; }' is not assignable to type 'string | SingleOrArray<TransitionConfig<EventsSearchContext, DoneInvokeEvent<any>>> | undefined'.
    Type '{ target: string; actions: AssignAction<unknown, any>; }' is not assignable to type 'TransitionConfig<EventsSearchContext, DoneInvokeEvent<any>>'.
      Types of property 'actions' are incompatible.
        Type 'AssignAction<unknown, any>' is not assignable to type 'Actions<EventsSearchContext, DoneInvokeEvent<any>> | undefined'.
          Type 'AssignAction<unknown, any>' is missing the following properties from type 'Action<EventsSearchContext, DoneInvokeEvent<any>>[]': length, pop, push, concat, and 29 more.

There is only one onDone, so hopefully it's clear where this is coming from.

There are no solutions on the web anywhere, but the troubleshooting page does mention a similar issue. I tried it, but it doesn't work unfortunately. Any ideas?

serlingpa
  • 12,024
  • 24
  • 80
  • 130

1 Answers1

1

When trying to reproduce, I found a solution that worked for me which is using the services schema property like in the official documentation

Something like the following could work I think:

import { createMachine, assign } from 'xstate'
    
interface EventsSearchContext  {
  questions: Question[];
}

const eventsSearchMachine = createMachine({
  schema: {
    context: {} as EventsSearchContext,
  },
  id: 'eventsSearch',
  initial: 'questions',
  context: {
    questions: []
  },
  states: {
    questions: {
      initial: 'loading',
      states: {
        loading: {
          invoke: {
            id: 'loadQuestions',
            src: 'fetchQuestions',
            onDone: {
              target: 'asking',
              actions: 'assignQuestion'
            },
            onError: 'asking',
          },
          tags: ['loading'],
        },
        asking: {
          always: [{
            target: '#search',
            cond: 'questionsExhausted'
          }],
          on: {
            QUESTION_ANSWERED: ''
          }
        }
      }
    },
    search: {
      id: 'search',
      initial: 'performingSearch',
      states: {
        performingSearch: {},
        displayingResults: {}
      }
    }
  }
}, {
  services: {
    fetchQuestions,
  },
  actions: {
    assignQuestion: assign({
      questions: (context, event: any) => event.data
    })
  }
})
Mohamed Sadat
  • 255
  • 1
  • 5