diff --git a/packages/core/index.d.ts b/packages/core/index.d.ts index 5a3d09fb..16ee1452 100644 --- a/packages/core/index.d.ts +++ b/packages/core/index.d.ts @@ -9,14 +9,23 @@ declare module 'robot3' { }[keyof T] : never - type AllStateKeys = NestedKeys | keyof T + type AllStateKeys = NestedKeys | keyof T; + + type MachineStates = { + [K in keyof S]: { + final: boolean + transitions: Map[]> + immediates?: Map[]> + enter?: any + } + } /** * The debugging object contains an _onEnter method, wich can be set to invoke * this function on every transition. */ export const d: { - _onEnter?: OnEnterFunction + _onEnter?: OnEnterFunction> } /** @@ -27,11 +36,11 @@ declare module 'robot3' { * @param states - An object of states, where each key is a state name, and the values are one of *state* or *invoke*. * @param context - A function that returns an object of extended state values. The function can receive an `event` argument. */ - export function createMachine( + export function createMachine, C = {}, F extends string = string>( initial: keyof S, - states: { [K in keyof S]: MachineState }, + states: S, context?: ContextFunction - ): Machine> + ): Machine> /** * The `createMachine` function creates a state machine. It takes an object of *states* with the key being the state name. * The value is usually *state* but might also be *invoke*. @@ -39,17 +48,19 @@ declare module 'robot3' { * @param states - An object of states, where each key is a state name, and the values are one of *state* or *invoke*. * @param context - A function that returns an object of extended state values. The function can receive an `event` argument. */ - export function createMachine( - states: { [K in keyof S]: MachineState }, + export function createMachine, C = {}, F extends string = string>( + states: S, context?: ContextFunction - ): Machine> + ): Machine>; /** * The `state` function returns a state object. A state can take transitions and immediates as arguments. * * @param args - Any argument needs to be of type Transition or Immediate. */ - export function state(...args: (Transition | Immediate)[]): MachineState + export function state | Immediate>( + ...args: T[] + ): MachineState ? F : string>; /** * A `transition` function is used to move from one state to another. @@ -58,11 +69,11 @@ declare module 'robot3' { * @param state - The name of the destination state. * @param args - Any extra argument will be evaluated to check if they are one of Reducer, Guard or Action. */ - export function transition( - event: string, + export function transition( + event: F, state: string, ...args: (Reducer | Guard | Action)[] - ): Transition + ): Transition; /** * An `immediate` function is a type of transition that occurs immediately; it doesn't wait for an event to proceed. @@ -71,10 +82,10 @@ declare module 'robot3' { * @param state - The name of the destination state. * @param args - Any extra argument will be evaluated to check if they are a Reducer or a Guard. */ - export function immediate( + export function immediate( state: string, ...args: (Reducer | Guard | Action)[] - ): Transition + ): Transition /** * A `guard` is a method that determines if a transition can proceed. @@ -119,7 +130,7 @@ declare module 'robot3' { * @param fn - Promise-returning function * @param args - Any argument needs to be of type Transition or Immediate. */ - export function invoke(fn: (ctx: C, e?: E) => Promise, ...args: (Transition | Immediate)[]): MachineState + export function invoke(fn: (ctx: C, e?: E) => Promise, ...args: (Transition | Immediate)[]): MachineState /** * The `invoke` is a special type of state that immediately invokes a Promise-returning or Machine-returning function, or another machine. @@ -127,7 +138,7 @@ declare module 'robot3' { * @param fn - Machine-returning function * @param args - Any argument needs to be of type Transition or Immediate. */ - export function invoke(fn: (ctx: C, e?: E) => M, ...args: (Transition | Immediate)[]): MachineState + export function invoke(fn: (ctx: C, e?: E) => M, ...args: (Transition | Immediate)[]): MachineState /** * The `invoke` is a special type of state that immediately invokes a Promise-returning or Machine-returning function, or another machine. @@ -135,7 +146,7 @@ declare module 'robot3' { * @param machine - Machine * @param args - Any argument needs to be of type Transition or Immediate. */ - export function invoke(machine: M, ...args: (Transition | Immediate)[]): MachineState + export function invoke(machine: M, ...args: (Transition | Immediate)[]): MachineState /* General Types */ @@ -151,8 +162,8 @@ declare module 'robot3' { service: Service ) => void - export type SendEvent = string | { type: string; [key: string]: any } - export type SendFunction = (event: T) => void + export type SendEvent = T | { type: T; [key: string]: any } + export type SendFunction = (event: SendEvent & {}) => void /** * This function is invoked before entering a new state and is bound to the debug @@ -164,16 +175,16 @@ declare module 'robot3' { * @param prevState - previous state * @param event - event provoking the state change */ - export type OnEnterFunction = + export type OnEnterFunction> = (machine: M, to: string, state: C, prevState: C, event?: SendEvent) => void - export type Machine = { + export type Machine = {}, C = {}, K = string, F extends string = string> = { context: C current: K states: S state: { name: K - value: MachineState + value: MachineState } } @@ -189,15 +200,15 @@ declare module 'robot3' { fn: GuardFunction } - export interface MachineState { + export interface MachineState { final: boolean - transitions: Map - immediates?: Map + transitions: Map[]> + immediates?: Map[]> enter?: any } - export interface Transition { - from: string | null + export interface Transition { + from: F | null to: string guards: any[] reducers: any[] @@ -208,8 +219,30 @@ declare module 'robot3' { machine: M context: M['context'] onChange: InterpretOnChangeFunction - send: SendFunction + send: SendFunction> + } + + export type Immediate = Transition; + + // Utilities + type IsAny = 0 extends (1 & T) ? true : false; + + // Get state objects from a Machine + type GetMachineStateObject = M['states']; + + // Create mapped type without the final indexing + type GetTransitionsFromStates = { + [K in keyof S]: S[K] extends { transitions: Map>> } + ? IsAny extends true + ? never + : F + : never } - export type Immediate = Transition + type ExtractNonAnyValues = { + [K in keyof T]: IsAny extends true ? never : T[K] + }[keyof T]; + + export type GetMachineTransitions = + ExtractNonAnyValues>>; }