DEV Community

Discussion on: Finite State Machine in JavaScript

Collapse
 
desibabe profile image
Desibabe

I am learning typescript, how do I convert this into ts? Thanks.

Collapse
 
viniciusfxavier profile image
Vinícius Francisco Xavier • Edited

State Transitions Flexibility: TypeScript Implementation

// machine.d.ts
declare type TransitionFunction = () => void;

declare type Transition = {
    [key: string]: TransitionFunction;
};

declare type State = {
    [key: string]: Transition;
};

declare type Machine = {
    state: string;
    transitions: State;
    dispatch: (actionName: string) => void;
};

// main.ts
import { Machine } from "./machine";

const machine: Machine = {
    state: 'OFF',
    transitions: {
        OFF: {
            press() {
                this.state = 'ON';
            }
        },
        ON: {
            press() {
                this.state = 'BLINK';
            }
        },
        BLINK: {
            press() {
                this.state = 'OFF';
            }
        }
    },
    dispatch(actionName: string) {
        const action = this.transitions[this.state][actionName];
        if (action) {
            action.call(this);
        } else {
            console.log('invalid action');
        }
    }
};

const flashlight: Machine = Object.create(machine);

console.log(flashlight.state); // OFF
flashlight.dispatch('press');
console.log(flashlight.state); // ON
flashlight.dispatch('press');
console.log(flashlight.state); // BLINK
Enter fullscreen mode Exit fullscreen mode

State Transitions No Flexible but Safety Typed: TypeScript Implementation

// machine.d.ts
export enum State {
    OFF = 'OFF',
    ON = 'ON',
    BLINK = 'BLINK'
}

declare type TransitionFunction = () => void;

declare type Transition = {
    [key in State]: TransitionFunction;
};

declare type Machine = {
    state: State;
    transitions: Transition;
    dispatch: (actionName: State) => void;
};

// main.ts
import { State, Machine } from "./machine";

const machine: Machine = {
    state: State.OFF,
    transitions: {
        [State.OFF]: {
            press() {
                this.state = State.ON;
            }
        },
        [State.ON]: {
            press() {
                this.state = State.BLINK;
            }
        },
        [State.BLINK]: {
            press() {
                this.state = State.OFF;
            }
        }
    },
    dispatch(actionName: State) {
        const action = this.transitions[this.state][actionName];
        if (action) {
            action.call(this);
        } else {
            console.log('invalid action');
        }
    }
};

const flashlight: Machine = Object.create(machine);

console.log(flashlight.state); // OFF
flashlight.dispatch(State.ON);
console.log(flashlight.state); // ON
flashlight.dispatch(State.BLINK);
console.log(flashlight.state); // BLINK
Enter fullscreen mode Exit fullscreen mode