Siglo is built from the ground up for modern TypeScript (strict mode, noImplicitAny, exactOptionalPropertyTypes).
1. Step Generics: Step<TInput, TOutput, TName>
Step.create(name, action):
TInput: Type expected by the step action parameter.TOutput: Type returned by the step action.TName: String literal name of the step (used to index$steps).
Generic Overloads
Step.create supports both explicit generic orders:
-
Name-First Overload (convenient when specifying literal step name as the leading type argument):
-
Input-First Overload (mirrors the class generic order
Step<TInput, TOutput, TName>): -
Automatic Inference (Recommended): In standard application code, TypeScript automatically infers
TName,TInput, andTOutputfrom the function arguments without manual type parameter annotations:
2. Accumulated Context Inference
When steps are chained inflow(s1, s2, s3):
- Step 1 receives
TInand returnsT1Out. - Step 2 receives
TIn & T1Outand returnsT2Out. - Step 3 receives
TIn & T1Out & T2Outand returnsT3Out. - The workflow execution returns
MergeStepContext<TIn, T1Out & T2Out & T3Out> & { $steps: Record<...> }.
3. Typed Step History: $steps
Every named step automatically registers its typed output in $steps:
4. Dependency Injection Typing
Define typed runtime dependencies per-step or per-workflow:5. Schema Validation Support
Siglo integrates with Standard Schema (~standard) compatible libraries including Zod, Valibot, and ArkType:
Minimal Example
Compile-Time Checking & Inference Boundaries
When steps declare explicit input generic types (Step.create<MyInput, ...>), TypeScript verifies whether upstream outputs provide the required properties:
[!NOTE] Inference Limits with Combinators & Long Pipelines: Type inference works seamlessly across sequential chains. However, across dynamic combinators (branch,when,map) or deep pipelines (5+ steps), TypeScript’s conditional type evaluation may widen accumulated intersection types or infer optional properties. For ironclad parameter validation across complex combinators and untrusted ingress boundaries, pair TypeScript definitions with runtime schema assertions (step.schema()orstep.spec()).
Testing Example
Operational Caveats
- Keep Step Generic Signatures Clean: In complex pipelines, rely on TypeScript’s inference rather than manually specifying all intermediate types for 10+ steps.
- Strict Mode: Ensure
"strict": trueis enabled intsconfig.jsonfor full compile-time inference benefits.
