Skip to content

Commit

Permalink
fix: allow any action payload if action was never typed (#5)
Browse files Browse the repository at this point in the history
[fix] correct some minor TypeScript definition bugs

* closes #4 - allow any event arguments if action types unspecified
* expect event invocations to always returns State (string | symbol)
  • Loading branch information
ivanhofer authored Dec 14, 2021
1 parent e5ca666 commit e7c00ad
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 11 deletions.
12 changes: 8 additions & 4 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ type LifecycleAction = (arg: {
args: Args;
}) => void;

type ActionFunction = BaseState | ((...args: Args) => BaseState) | ((...args: Args) => void);
type AllArgsAction = ((...args: Args) => BaseState)

type VoidFunction = ((...args: Args) => void)

type ActionFunction = BaseState | AllArgsAction | VoidFunction;

type BaseActions = {
_enter?: LifecycleAction;
Expand All @@ -29,8 +33,8 @@ type ExtractObjectValues<Object> = Object[keyof Object];

type GetActionFunctionMapping<Actions extends BaseActions> = {
[Key in Exclude<keyof Actions, '_enter' | '_exit'>]: Actions[Key] extends BaseState
? () => Actions[Key]
: Actions[Key];
? () => Actions[Key] extends void ? BaseState : Actions[Key]
: Actions[Key] extends VoidFunction ? ((...args: Parameters<Actions[Key]>) => BaseState) : Actions[Key]
};

type GetActionMapping<States extends BaseStates> = ExtractObjectValues<{
Expand All @@ -44,7 +48,7 @@ type Unsubscribe = () => void;
type Subscribe<S extends BaseState> = (callback: (state: S) => void) => Unsubscribe;

type StateMachine<State extends BaseState, Actions> = {
[Key in keyof Actions]: Actions[Key];
[Key in keyof Actions]: Actions[Key] | AllArgsAction;
} & {
subscribe: Subscribe<State>;
};
Expand Down
16 changes: 9 additions & 7 deletions test/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ unsub();
// @ts-expect-error state machine expects valid event invocation
valid1.noSuchAction();

// @ts-expect-error toggle expects no arguments (1 provided)
valid1.toggle(1);
// can pass any argument if action get's never typed
valid1.toggle();
valid1.toggle(1);
valid1.toggle(true, 1);
valid1.toggle("test", true, 1);

const toggleResultValid: string | symbol = valid1.toggle();
// @ts-expect-error toggle returns string or symbol
Expand Down Expand Up @@ -88,13 +90,13 @@ valid3.overloaded('string', 2);
// @ts-expect-error overloaded expects 1 or 2 args (3 provided)
valid3.overloaded(1, 2, 3);

// @ts-expect-error overloaded with single argument returns string | void
// @ts-expect-error overloaded with single argument returns string | symbol
const overloadedResult1Invalid: void = valid3.overloaded(1);
const overloadedResult1Valid: string | void = valid3.overloaded(1);
const overloadedResult1Valid: string | symbol = valid3.overloaded(1);

// @ts-expect-error overloaded with two arguments returns only void
const overloadedResult2Invalid: string = valid3.overloaded('string', 1);
const overloadedResult2Valid: string | void = valid3.overloaded('string', 1);
// @ts-expect-error overloaded with two arguments returns string | symbol
const overloadedResult2Invalid: void = valid3.overloaded('string', 1);
const overloadedResult2Valid: string | symbol = valid3.overloaded('string', 1);

// A state machine that uses symbols as a state keys
const valid4 = fsm(Symbol.for('foo'), {
Expand Down

0 comments on commit e7c00ad

Please sign in to comment.