Xstate: Object Getters Typescript

Created on 24 Sep 2019  路  8Comments  路  Source: davidkpiano/xstate

Bug or feature request?

Question

Description:

How to use Object getters with Typescript?

question

Most helpful comment

Workaround for me is to always use enums/objects as you can also use them within your type definitions and components for easier refactoring and more type safety.

enum TOGGGLE {
  "INACTIVE" = "inactive",
  "ACTIVE" = "active"
}

const machine = Machine<Context, Schema, Event>({
  id: "machine",
  initial: TOGGLE.INACTIVE,
  context: {
    count: 0
  },
  states: {
    [TOGGLE.INACTIVE]: {
      on: {
        TOGGLE: [
          {
            target: TOGGLE.ACTIVE
          }
        ]
      }
    },
    [TOGGLE.ACTIVE]: {
      on: {
        TOGGLE: [
          {
           target: TOGGLE.INACTIVE
          }
        ]
      }
    }
  }
});

Makes it a bit harder to read imo but well worth the effort since your components can now also use the string enum:
state.matches(TOGGLE.INACTIVE)

All 8 comments

Exactly as it says in the docs.

You can also look at id.test.ts: https://github.com/davidkpiano/xstate/blob/master/test/id.test.ts as these tests are written in TypeScript.

Ok i added one example here with strict:

{
  "compilerOptions": {
    "strict": true
  }
}

The getter returns:

'target' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.

I tried:

const machine = Machine<Context, Schema, Event>({
  id: "machine",
  initial: "inactive",
  context: {
    count: 0
  },
  states: {
    inactive: {
      on: {
        TOGGLE: [
          {
            //target: "active"
            get target() {
              return machine.states.active;
            }
          }
        ]
      }
    },
    active: {
      on: {
        TOGGLE: [
          {
            // "inactive"
            get target(): StateNode<Context, {}, Event> {
              return machine.states.inactive;
            }
          }
        ]
      }
    }
  }
});

But neither approach worked, from string it complains that StateNode is not assignable, and then goes with StateNodeConfig and then TransitionConfig, also tried with TransitionTarget, it never settles.

What is the correct type for target to return ?

What version of TypeScript do you have? It should work with just those states. See if the Schema might have anything to do with the problems (set it to any)

could this be re-opened please 馃檹 ?

I tried with [email protected] and 3.6.3 but nothing changed. It works ok without strict

Is there a workaround for this?

Workaround for me is to always use enums/objects as you can also use them within your type definitions and components for easier refactoring and more type safety.

enum TOGGGLE {
  "INACTIVE" = "inactive",
  "ACTIVE" = "active"
}

const machine = Machine<Context, Schema, Event>({
  id: "machine",
  initial: TOGGLE.INACTIVE,
  context: {
    count: 0
  },
  states: {
    [TOGGLE.INACTIVE]: {
      on: {
        TOGGLE: [
          {
            target: TOGGLE.ACTIVE
          }
        ]
      }
    },
    [TOGGLE.ACTIVE]: {
      on: {
        TOGGLE: [
          {
           target: TOGGLE.INACTIVE
          }
        ]
      }
    }
  }
});

Makes it a bit harder to read imo but well worth the effort since your components can now also use the string enum:
state.matches(TOGGLE.INACTIVE)

Thanks @CodingDive ! I do also use const as const to refer string whenever possible 馃憤 .

I guess this should stay open until Object getters work with ts in strict mode.

Closing this as getters for targets will be removed in V5. Other userland-implemented patterns for building machines will be preferred, rather than baking this into the core API.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bradwoods picture bradwoods  路  3Comments

hnordt picture hnordt  路  3Comments

bradwoods picture bradwoods  路  3Comments

rodinhart picture rodinhart  路  3Comments

laurentpierson picture laurentpierson  路  3Comments