@@ -40,6 +40,20 @@ type AwaitedReturn<T> = T extends (...args: any[]) => Promise<infer R>
4040 ? R
4141 : never ;
4242
43+ type WidenJson < T > = T extends string
44+ ? string
45+ : T extends number
46+ ? number
47+ : T extends boolean
48+ ? boolean
49+ : T extends null
50+ ? null
51+ : T extends readonly ( infer U ) [ ]
52+ ? WidenJson < U > [ ]
53+ : T extends object
54+ ? { [ K in keyof T ] : WidenJson < T [ K ] > }
55+ : T ;
56+
4357// ========================
4458// ENVIRONMENT TYPE SYSTEM
4559// ========================
@@ -144,8 +158,16 @@ export type ExtractFlowOutput<TFlow extends AnyFlow> = TFlow extends Flow<
144158>
145159 ? {
146160 [ K in keyof ExtractFlowLeafSteps < TFlow > as K extends string
147- ? K
161+ ? GetSkippableMode < TFlow , K > extends false
162+ ? K
163+ : never
148164 : never ] : StepOutput < TFlow , K & string > ;
165+ } & {
166+ [ K in keyof ExtractFlowLeafSteps < TFlow > as K extends string
167+ ? GetSkippableMode < TFlow , K > extends false
168+ ? never
169+ : K
170+ : never ] ?: StepOutput < TFlow , K & string > ;
149171 }
150172 : never ;
151173
@@ -716,7 +738,10 @@ export class Flow<
716738 // Overload 1: Root step without conditions
717739 step <
718740 Slug extends string ,
719- TOutput ,
741+ THandler extends (
742+ flowInput : TFlowInput ,
743+ context : FlowContext < TEnv , TFlowInput > & TContext
744+ ) => Json | Promise < Json > ,
720745 TRetries extends WhenExhaustedMode | undefined = undefined
721746 > (
722747 opts : Simplify <
@@ -727,16 +752,13 @@ export class Flow<
727752 } & WithoutCondition &
728753 Omit < BaseStepRuntimeOptions , 'whenExhausted' >
729754 > ,
730- handler : (
731- flowInput : TFlowInput ,
732- context : FlowContext < TEnv , TFlowInput > & TContext
733- ) => TOutput | Promise < TOutput >
755+ handler : THandler
734756 ) : Flow <
735757 TFlowInput ,
736758 TContext ,
737759 Steps & {
738760 [ K in Slug ] : StepMeta <
739- Awaited < TOutput > ,
761+ WidenJson < AwaitedReturn < THandler > > ,
740762 TRetries extends 'skip' | 'skip-cascade' ? TRetries : false
741763 > ;
742764 } ,
@@ -747,7 +769,10 @@ export class Flow<
747769 // Overload 2: Root step with condition and omitted whenUnmet defaults to 'skip'
748770 step <
749771 Slug extends string ,
750- TOutput ,
772+ THandler extends (
773+ flowInput : TFlowInput ,
774+ context : FlowContext < TEnv , TFlowInput > & TContext
775+ ) => Json | Promise < Json > ,
751776 TRetries extends WhenExhaustedMode | undefined = undefined
752777 > (
753778 opts : Simplify <
@@ -761,15 +786,12 @@ export class Flow<
761786 ) &
762787 Omit < BaseStepRuntimeOptions , 'whenExhausted' >
763788 > ,
764- handler : (
765- flowInput : TFlowInput ,
766- context : FlowContext < TEnv , TFlowInput > & TContext
767- ) => TOutput | Promise < TOutput >
789+ handler : THandler
768790 ) : Flow <
769791 TFlowInput ,
770792 TContext ,
771793 Steps & {
772- [ K in Slug ] : StepMeta < Awaited < TOutput > , 'skip' > ;
794+ [ K in Slug ] : StepMeta < WidenJson < AwaitedReturn < THandler > > , 'skip' > ;
773795 } ,
774796 StepDependencies & { [ K in Slug ] : [ ] } ,
775797 TEnv
@@ -778,7 +800,10 @@ export class Flow<
778800 // Overload 3: Root step with explicit whenUnmet
779801 step <
780802 Slug extends string ,
781- TOutput ,
803+ THandler extends (
804+ flowInput : TFlowInput ,
805+ context : FlowContext < TEnv , TFlowInput > & TContext
806+ ) => Json | Promise < Json > ,
782807 TWhenUnmet extends WhenUnmetMode ,
783808 TRetries extends WhenExhaustedMode | undefined = undefined
784809 > (
@@ -793,16 +818,13 @@ export class Flow<
793818 ) &
794819 Omit < BaseStepRuntimeOptions , 'whenExhausted' >
795820 > ,
796- handler : (
797- flowInput : TFlowInput ,
798- context : FlowContext < TEnv , TFlowInput > & TContext
799- ) => TOutput | Promise < TOutput >
821+ handler : THandler
800822 ) : Flow <
801823 TFlowInput ,
802824 TContext ,
803825 Steps & {
804826 [ K in Slug ] : StepMeta <
805- Awaited < TOutput > ,
827+ WidenJson < AwaitedReturn < THandler > > ,
806828 TWhenUnmet extends 'skip' | 'skip-cascade'
807829 ? TWhenUnmet
808830 : TRetries extends 'skip' | 'skip-cascade'
@@ -818,7 +840,10 @@ export class Flow<
818840 step <
819841 Slug extends string ,
820842 Deps extends Extract < keyof Steps , string > ,
821- TOutput ,
843+ THandler extends (
844+ deps : Simplify < DepsWithOptionalSkippable < Steps , Deps > > ,
845+ context : FlowContext < TEnv , TFlowInput > & TContext
846+ ) => Json | Promise < Json > ,
822847 TRetries extends WhenExhaustedMode | undefined = undefined
823848 > (
824849 opts : Simplify <
@@ -829,16 +854,13 @@ export class Flow<
829854 } & WithoutCondition &
830855 Omit < BaseStepRuntimeOptions , 'whenExhausted' >
831856 > ,
832- handler : (
833- deps : Simplify < DepsWithOptionalSkippable < Steps , Deps > > ,
834- context : FlowContext < TEnv , TFlowInput > & TContext
835- ) => TOutput | Promise < TOutput >
857+ handler : THandler
836858 ) : Flow <
837859 TFlowInput ,
838860 TContext ,
839861 Steps & {
840862 [ K in Slug ] : StepMeta <
841- Awaited < TOutput > ,
863+ WidenJson < AwaitedReturn < THandler > > ,
842864 TRetries extends 'skip' | 'skip-cascade' ? TRetries : false
843865 > ;
844866 } ,
@@ -850,7 +872,10 @@ export class Flow<
850872 step <
851873 Slug extends string ,
852874 Deps extends Extract < keyof Steps , string > ,
853- TOutput ,
875+ THandler extends (
876+ deps : Simplify < DepsWithOptionalSkippable < Steps , Deps > > ,
877+ context : FlowContext < TEnv , TFlowInput > & TContext
878+ ) => Json | Promise < Json > ,
854879 TRetries extends WhenExhaustedMode | undefined = undefined
855880 > (
856881 opts : Simplify <
@@ -870,15 +895,12 @@ export class Flow<
870895 ) &
871896 Omit < BaseStepRuntimeOptions , 'whenExhausted' >
872897 > ,
873- handler : (
874- deps : Simplify < DepsWithOptionalSkippable < Steps , Deps > > ,
875- context : FlowContext < TEnv , TFlowInput > & TContext
876- ) => TOutput | Promise < TOutput >
898+ handler : THandler
877899 ) : Flow <
878900 TFlowInput ,
879901 TContext ,
880902 Steps & {
881- [ K in Slug ] : StepMeta < Awaited < TOutput > , 'skip' > ;
903+ [ K in Slug ] : StepMeta < WidenJson < AwaitedReturn < THandler > > , 'skip' > ;
882904 } ,
883905 StepDependencies & { [ K in Slug ] : Deps [ ] } ,
884906 TEnv
@@ -888,7 +910,10 @@ export class Flow<
888910 step <
889911 Slug extends string ,
890912 Deps extends Extract < keyof Steps , string > ,
891- TOutput ,
913+ THandler extends (
914+ deps : Simplify < DepsWithOptionalSkippable < Steps , Deps > > ,
915+ context : FlowContext < TEnv , TFlowInput > & TContext
916+ ) => Json | Promise < Json > ,
892917 TWhenUnmet extends WhenUnmetMode ,
893918 TRetries extends WhenExhaustedMode | undefined = undefined
894919 > (
@@ -907,16 +932,13 @@ export class Flow<
907932 ) &
908933 Omit < BaseStepRuntimeOptions , 'whenExhausted' >
909934 > ,
910- handler : (
911- deps : Simplify < DepsWithOptionalSkippable < Steps , Deps > > ,
912- context : FlowContext < TEnv , TFlowInput > & TContext
913- ) => TOutput | Promise < TOutput >
935+ handler : THandler
914936 ) : Flow <
915937 TFlowInput ,
916938 TContext ,
917939 Steps & {
918940 [ K in Slug ] : StepMeta <
919- Awaited < TOutput > ,
941+ WidenJson < AwaitedReturn < THandler > > ,
920942 TWhenUnmet extends 'skip' | 'skip-cascade'
921943 ? TWhenUnmet
922944 : TRetries extends 'skip' | 'skip-cascade'
0 commit comments