diff --git a/index.d.ts b/index.d.ts index f2d3c1a..beca264 100644 --- a/index.d.ts +++ b/index.d.ts @@ -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; @@ -29,8 +33,8 @@ type ExtractObjectValues = Object[keyof Object]; type GetActionFunctionMapping = { [Key in Exclude]: Actions[Key] extends BaseState - ? () => Actions[Key] - : Actions[Key]; + ? () => Actions[Key] extends void ? BaseState : Actions[Key] + : Actions[Key] extends VoidFunction ? ((...args: Parameters) => BaseState) : Actions[Key] }; type GetActionMapping = ExtractObjectValues<{ @@ -44,7 +48,7 @@ type Unsubscribe = () => void; type Subscribe = (callback: (state: S) => void) => Unsubscribe; type StateMachine = { - [Key in keyof Actions]: Actions[Key]; + [Key in keyof Actions]: Actions[Key] | AllArgsAction; } & { subscribe: Subscribe; }; diff --git a/test/types.ts b/test/types.ts index d53acd4..e80dc0c 100644 --- a/test/types.ts +++ b/test/types.ts @@ -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 @@ -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'), {