diff --git a/lib/arrayBlock.ts b/lib/arrayBlock.ts index ccddeab..2ba209c 100644 --- a/lib/arrayBlock.ts +++ b/lib/arrayBlock.ts @@ -1,10 +1,9 @@ import CompositeBlock from './compositeBlock'; import { createError, ERROR_ID } from './error'; -import type { DescriptError } from './error'; import type { BlockResultOut, First, - InferResultFromBlock, + InferResultOrError, InferParamsInFromBlock, Tail, DescriptBlockOptions, @@ -17,8 +16,8 @@ import type DepsDomain from './depsDomain'; export type GetArrayBlockResult> = { 0: never; - 1: [ InferResultFromBlock> | DescriptError ]; - 2: [ InferResultFromBlock> | DescriptError, ...GetArrayBlockResult> ]; + 1: [ InferResultOrError> ]; + 2: [ InferResultOrError>, ...GetArrayBlockResult> ]; }[ T extends [] ? 0 : T extends ((readonly [ any ]) | [ any ]) ? 1 : 2 ]; export type GetArrayBlockParamsUnion> = { @@ -72,20 +71,42 @@ class ArrayBlock< > { extend< - // eslint-disable-next-line @typescript-eslint/no-unused-vars - ExtendedResultOut extends - BlockResultOut, + ExtendedResultOut extends BlockResultOut, + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >(args: { + options: DescriptBlockOptions & { required: true }; + }): ArrayBlock & { readonly __isRequired: true }; + extend< + ExtendedResultOut extends BlockResultOut, + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >( + this: ArrayBlock & { readonly __isRequired: true }, + args: { + options?: DescriptBlockOptions & { required?: true }; + } + ): ArrayBlock & { readonly __isRequired: true }; + extend< + ExtendedResultOut extends BlockResultOut, ExtendedParamsOut extends Params = Params, ExtendedParams = Params, ExtendedBlockResult = ResultOut, ExtendedBeforeResultOut = unknown, ExtendedAfterResultOut = unknown, ExtendedErrorResultOut = unknown, - >({ options }: { - options: DescriptBlockOptions< - Context, ExtendedParamsOut, ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams - >; - }) { + >(args: { + options?: DescriptBlockOptions; + }): ArrayBlock; + extend({ options }: { options?: any }): any { return new ArrayBlock({ block: this.extendBlock(this.block), options: this.extendOptions(this.options, options) as typeof options, diff --git a/lib/block.ts b/lib/block.ts index 90982a8..4d8390f 100644 --- a/lib/block.ts +++ b/lib/block.ts @@ -66,27 +66,40 @@ abstract class BaseBlock< } abstract extend< - - // ExtendedResultOut extends - // BlockResultOut, ExtendedParamsOut extends Params = Params, ExtendedParams = Params, - // ExtendedCustomBlock = CustomBlock, ExtendedBlockResult = ResultOut, ExtendedBeforeResultOut = unknown, ExtendedAfterResultOut = unknown, ExtendedErrorResultOut = unknown, - >({ block, options }: { + >(args: { block?: CustomBlock; - options?: DescriptBlockOptions< - Context, - ParamsOut & ExtendedParamsOut, - ExtendedBlockResult, - ExtendedBeforeResultOut, - ExtendedAfterResultOut, - ExtendedErrorResultOut, - ExtendedParams - >; + options: DescriptBlockOptions & { required: true }; + }): unknown; + abstract extend< + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >( + this: BaseBlock & { readonly __isRequired: true }, + args: { + block?: CustomBlock; + options?: DescriptBlockOptions & { required?: true }; + } + ): unknown; + abstract extend< + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >(args: { + block?: CustomBlock; + options?: DescriptBlockOptions; }): unknown; protected initBlock(block: CustomBlock) { diff --git a/lib/firstBlock.ts b/lib/firstBlock.ts index 24e2db8..cfb693c 100644 --- a/lib/firstBlock.ts +++ b/lib/firstBlock.ts @@ -5,7 +5,7 @@ import type BaseBlock from './block'; import type { BlockResultOut, First, - InferResultFromBlock, + InferResultOrError, InferParamsInFromBlock, Tail, DescriptBlockOptions, @@ -32,21 +32,14 @@ export type GetFirstBlockParams< PU = GetFirstBlockParamsUnion, > = PU; -type GetFirstBlockResultMap> = { - [ P in keyof T ]: InferResultFromBlock; -}; - type GetFirstBlockResultUnion> = { 0: never; - 1: First | DescriptError; - 2: First | DescriptError | GetFirstBlockResultUnion>; + 1: InferResultOrError>; + 2: InferResultOrError> | GetFirstBlockResultUnion>; }[ T extends [] ? 0 : T extends ((readonly [ any ]) | [ any ]) ? 1 : 2 ]; -export type GetFirstBlockResult< - T extends ReadonlyArray, - PA extends ReadonlyArray = GetFirstBlockResultMap, - PU = GetFirstBlockResultUnion, -> = PU; +export type GetFirstBlockResult> = + GetFirstBlockResultUnion; export type FirstBlockDefinition = { [ P in keyof T ]: T[ P ] extends BaseBlock< @@ -83,21 +76,42 @@ class FirstBlock< > { extend< - // eslint-disable-next-line @typescript-eslint/no-unused-vars - ExtendedResultOut extends - BlockResultOut, - // ExtendedCustomBlock extends FirstBlockDefinition, + ExtendedResultOut extends BlockResultOut, + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >(args: { + options: DescriptBlockOptions & { required: true }; + }): FirstBlock & { readonly __isRequired: true }; + extend< + ExtendedResultOut extends BlockResultOut, + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >( + this: FirstBlock & { readonly __isRequired: true }, + args: { + options?: DescriptBlockOptions & { required?: true }; + } + ): FirstBlock & { readonly __isRequired: true }; + extend< + ExtendedResultOut extends BlockResultOut, ExtendedParamsOut extends Params = Params, ExtendedParams = Params, ExtendedBlockResult = ResultOut, ExtendedBeforeResultOut = unknown, ExtendedAfterResultOut = unknown, ExtendedErrorResultOut = unknown, - >({ options }: { - options: DescriptBlockOptions< - Context, ExtendedParamsOut, ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams - >; - }) { + >(args: { + options?: DescriptBlockOptions; + }): FirstBlock; + extend({ options }: { options?: any }): any { return new FirstBlock({ block: this.extendBlock(this.block), options: this.extendOptions(this.options, options) as typeof options, diff --git a/lib/functionBlock.ts b/lib/functionBlock.ts index 29234b7..c53d75d 100644 --- a/lib/functionBlock.ts +++ b/lib/functionBlock.ts @@ -97,28 +97,39 @@ class FunctionBlock< extend< ExtendedParamsOut extends Params = Params, ExtendedParams = Params, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - // ExtendedCustomBlock = DescriptHttpBlockDescription, - ExtendedBlockResult = ResultOut, ExtendedBeforeResultOut = unknown, ExtendedAfterResultOut = unknown, ExtendedErrorResultOut = unknown, - >({ options }: { - options: DescriptBlockOptions< - Context, - ExtendedParamsOut, - ExtendedBlockResult, - ExtendedBeforeResultOut, - ExtendedAfterResultOut, - ExtendedErrorResultOut, - ExtendedParams - >; - }) { + >(args: { + options: DescriptBlockOptions & { required: true }; + }): FunctionBlock, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams> & { readonly __isRequired: true }; + extend< + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >( + this: FunctionBlock & { readonly __isRequired: true }, + args: { + options?: DescriptBlockOptions & { required?: true }; + } + ): FunctionBlock, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams> & { readonly __isRequired: true }; + extend< + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >(args: { + options?: DescriptBlockOptions; + }): FunctionBlock, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams>; + extend({ options }: { options?: any }): any { return new FunctionBlock({ block: this.extendBlock(this.block) as typeof this.block, - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error options: this.extendOptions(this.options, options) as typeof options, }); } diff --git a/lib/httpBlock.ts b/lib/httpBlock.ts index 27a3007..c0958fd 100644 --- a/lib/httpBlock.ts +++ b/lib/httpBlock.ts @@ -205,30 +205,43 @@ class HttpBlock< ExtendedResultOut extends BlockResultOut, ExtendedParamsOut extends Params = Params, ExtendedParams = Params, - - // ExtendedCustomBlock = DescriptHttpBlockDescription, - ExtendedBlockResult = ResultOut, ExtendedBeforeResultOut = unknown, ExtendedAfterResultOut = unknown, ExtendedErrorResultOut = unknown, - >({ options, block }: { + >(args: { block?: DescriptHttpBlockDescription; - options?: DescriptBlockOptions< - Context, ExtendedParamsOut, ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams - >; - }) { - const x = new HttpBlock< - Context, - ExtendedParamsOut, - HttpResult, - ExtendedResultOut, - ExtendedBlockResult, - ExtendedBeforeResultOut, - ExtendedAfterResultOut, - ExtendedErrorResultOut, - ExtendedParams - >({ + options: DescriptBlockOptions & { required: true }; + }): HttpBlock & { readonly __isRequired: true }; + extend< + ExtendedResultOut extends BlockResultOut, + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >( + this: HttpBlock & { readonly __isRequired: true }, + args: { + block?: DescriptHttpBlockDescription; + options?: DescriptBlockOptions & { required?: true }; + } + ): HttpBlock & { readonly __isRequired: true }; + extend< + ExtendedResultOut extends BlockResultOut, + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >(args: { + block?: DescriptHttpBlockDescription; + options?: DescriptBlockOptions; + }): HttpBlock; + extend({ options, block }: { block?: any; options?: any }): any { + const x = new HttpBlock({ block: this.extendBlock(block), options: this.extendOptions(this.options, options), }); diff --git a/lib/index.ts b/lib/index.ts index a1c745d..19107d6 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -24,6 +24,8 @@ import type { DescriptBlockOptions, DescriptHttpBlockHeaders, InferResultFromBlock, + DeepInferResultFromBlock, + DeepResolveResult, InferParamsInFromBlock, InferBlock, InferHttpBlock, @@ -32,116 +34,205 @@ import type { } from './types'; import type BaseBlock from './block'; import type { DescriptHttpBlockDescription, DescriptHttpBlockQuery, DescriptHttpBlockQueryValue } from './httpBlock'; -import type { GetObjectBlockParams, GetObjectBlockResult, ObjectBlockDefinition } from './objectBlock'; +import type { GetObjectBlockParams, GetObjectBlockResult } from './objectBlock'; import type { GetArrayBlockParams, GetArrayBlockResult, ArrayBlockDefinition } from './arrayBlock'; import type { GetFirstBlockParams, GetFirstBlockResult, FirstBlockDefinition } from './firstBlock'; import type { GetPipeBlockParams, GetPipeBlockResult, PipeBlockDefinition } from './pipeBlock'; import PipeBlock from './pipeBlock'; -const func = function< - Context, - ParamsOut, - BlockResult, - ResultOut extends BlockResultOut, - BeforeResultOut = unknown, - AfterResultOut = unknown, - ErrorResultOut = unknown, - Params = ParamsOut, ->({ block, options }: { - block: FunctionBlockDefinition; - options?: DescriptBlockOptions< - Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params - >; -} & ([ ExtractBadNestedParams ] extends [ never ] ? unknown : ExtractBadNestedParams)) { - return new FunctionBlock< - Context, ParamsOut, BlockResult, ResultOut, BeforeResultOut, AfterResultOut, ErrorResultOut, Params - >({ block, options }); +const func: { + < + Context, + ParamsOut, + BlockResult, + ResultOut extends BlockResultOut, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = ParamsOut, + >(args: { + block: FunctionBlockDefinition; + options: DescriptBlockOptions & { required: true }; + } & ([ ExtractBadNestedParams ] extends [ never ] ? unknown : ExtractBadNestedParams)): FunctionBlock & { readonly __isRequired: true }; + < + Context, + ParamsOut, + BlockResult, + ResultOut extends BlockResultOut, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = ParamsOut, + >(args: { + block: FunctionBlockDefinition; + options?: DescriptBlockOptions; + } & ([ ExtractBadNestedParams ] extends [ never ] ? unknown : ExtractBadNestedParams)): FunctionBlock; +} = function({ block, options }: any): any { + return new FunctionBlock({ block, options }); }; -const array = function< - Context, - Block extends ReadonlyArray, - ResultOut extends BlockResultOut, - ParamsOut = GetArrayBlockParams, - BlockResult = GetArrayBlockResult, - BeforeResultOut = unknown, - AfterResultOut = unknown, - ErrorResultOut = unknown, - Params = GetArrayBlockParams, ->({ block, options }: { - block: ArrayBlockDefinition; - options?: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>; -}) { - return new ArrayBlock({ block, options }); +const array: { + < + Context, + Block extends ReadonlyArray, + ResultOut extends BlockResultOut, + ParamsOut = GetArrayBlockParams, + BlockResult = GetArrayBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = GetArrayBlockParams, + >(args: { + block: ArrayBlockDefinition; + options: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required: true }; + }): ArrayBlock & { readonly __isRequired: true }; + < + Context, + Block extends ReadonlyArray, + ResultOut extends BlockResultOut, + ParamsOut = GetArrayBlockParams, + BlockResult = GetArrayBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = GetArrayBlockParams, + >(args: { + block: ArrayBlockDefinition; + options?: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>; + }): ArrayBlock; +} = function({ block, options }: any): any { + return new ArrayBlock({ block, options }); }; -const object = function< - Context, - Blocks extends Record, - ResultOut extends BlockResultOut, - ParamsOut = GetObjectBlockParams, - BlockResult = GetObjectBlockResult, - - BeforeResultOut = unknown, - AfterResultOut = unknown, - ErrorResultOut = unknown, - Params = GetObjectBlockParams, ->({ block, options }: { - block?: ObjectBlockDefinition; - options?: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>; -} = {}) { - return new ObjectBlock({ block, options }); +const object: { + < + Context, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Blocks extends Record, + ResultOut extends BlockResultOut, + ParamsOut = GetObjectBlockParams, + BlockResult = GetObjectBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = GetObjectBlockParams, + >(args: { + block?: Blocks; + options: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required: true }; + }): ObjectBlock & { readonly __isRequired: true }; + < + Context, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Blocks extends Record, + ResultOut extends BlockResultOut, + ParamsOut = GetObjectBlockParams, + BlockResult = GetObjectBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = GetObjectBlockParams, + >(args?: { + block?: Blocks; + options?: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>; + }): ObjectBlock; +} = function({ block, options }: any = {}): any { + return new ObjectBlock({ block, options }); }; -const http = function< - Context, - ParamsOut, - ResultOut extends BlockResultOut, - IntermediateResult, - BlockResult extends DescriptHttpBlockResult, - - BeforeResultOut = unknown, - AfterResultOut = unknown, - ErrorResultOut = unknown, - Params = ParamsOut, ->({ block, options }: { - block?: DescriptHttpBlockDescription; - options?: DescriptBlockOptions; -}) { - return new HttpBlock< - Context, ParamsOut, IntermediateResult, ResultOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params - >({ block, options }); +const http: { + < + Context, + ParamsOut, + ResultOut extends BlockResultOut, + IntermediateResult, + BlockResult extends DescriptHttpBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = ParamsOut, + >(args: { + block?: DescriptHttpBlockDescription; + options: DescriptBlockOptions & { required: true }; + }): HttpBlock & { readonly __isRequired: true }; + < + Context, + ParamsOut, + ResultOut extends BlockResultOut, + IntermediateResult, + BlockResult extends DescriptHttpBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = ParamsOut, + >(args: { + block?: DescriptHttpBlockDescription; + options?: DescriptBlockOptions; + }): HttpBlock; +} = function({ block, options }: any): any { + return new HttpBlock({ block, options }); }; -const first = function< - Context, - Block extends ReadonlyArray, - ResultOut extends BlockResultOut, - ParamsOut = GetFirstBlockParams, - BlockResult = GetFirstBlockResult, - BeforeResultOut = unknown, - AfterResultOut = unknown, - ErrorResultOut = unknown, - Params = GetFirstBlockParams, ->({ block, options }: { - block: FirstBlockDefinition; - options?: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>; -}) { - return new FirstBlock({ block, options }); +const first: { + < + Context, + Block extends ReadonlyArray, + ResultOut extends BlockResultOut, + ParamsOut = GetFirstBlockParams, + BlockResult = GetFirstBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = GetFirstBlockParams, + >(args: { + block: FirstBlockDefinition; + options: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required: true }; + }): FirstBlock & { readonly __isRequired: true }; + < + Context, + Block extends ReadonlyArray, + ResultOut extends BlockResultOut, + ParamsOut = GetFirstBlockParams, + BlockResult = GetFirstBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = GetFirstBlockParams, + >(args: { + block: FirstBlockDefinition; + options?: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>; + }): FirstBlock; +} = function({ block, options }: any): any { + return new FirstBlock({ block, options }); }; -const pipe = function< - Context, - Block extends ReadonlyArray, - ResultOut extends BlockResultOut, - ParamsOut = GetPipeBlockParams, - BlockResult = GetPipeBlockResult, - BeforeResultOut = unknown, - AfterResultOut = unknown, - ErrorResultOut = unknown, - Params = GetPipeBlockParams, ->({ block, options }: { - block: PipeBlockDefinition; - options?: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>; -}) { - return new PipeBlock({ block, options }); +const pipe: { + < + Context, + Block extends ReadonlyArray, + ResultOut extends BlockResultOut, + ParamsOut = GetPipeBlockParams, + BlockResult = GetPipeBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = GetPipeBlockParams, + >(args: { + block: PipeBlockDefinition; + options: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params> & { required: true }; + }): PipeBlock & { readonly __isRequired: true }; + < + Context, + Block extends ReadonlyArray, + ResultOut extends BlockResultOut, + ParamsOut = GetPipeBlockParams, + BlockResult = GetPipeBlockResult, + BeforeResultOut = unknown, + AfterResultOut = unknown, + ErrorResultOut = unknown, + Params = GetPipeBlockParams, + >(args: { + block: PipeBlockDefinition; + options?: DescriptBlockOptions, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>; + }): PipeBlock; +} = function({ block, options }: any): any { + return new PipeBlock({ block, options }); }; const isBlock = function(block: any) { @@ -211,6 +302,8 @@ export { GenerateId, DescriptBlockId, InferResultFromBlock, + DeepInferResultFromBlock, + DeepResolveResult, InferParamsInFromBlock, InferBlock, DescriptBlockDeps, diff --git a/lib/objectBlock.ts b/lib/objectBlock.ts index 5e7500e..f73135e 100644 --- a/lib/objectBlock.ts +++ b/lib/objectBlock.ts @@ -18,7 +18,9 @@ export type InferResultFromObjectBlocks = Block extends BaseBlock< Block; export type GetObjectBlockResult> = { - [ P in keyof T ]: InferResultFromBlock | DescriptError + [ P in keyof T ]: T[P] extends { readonly __isRequired: true } + ? InferResultFromBlock + : InferResultFromBlock | DescriptError }; export type GetObjectBlockParams< @@ -106,21 +108,42 @@ class ObjectBlock< } extend< - // eslint-disable-next-line @typescript-eslint/no-unused-vars - ExtendedResultOut extends - BlockResultOut, - // ExtendedCustomBlock extends ObjectBlockDefinition, + ExtendedResultOut extends BlockResultOut, + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >(args: { + options: DescriptBlockOptions & { required: true }; + }): ObjectBlock & { readonly __isRequired: true }; + extend< + ExtendedResultOut extends BlockResultOut, + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >( + this: ObjectBlock & { readonly __isRequired: true }, + args: { + options?: DescriptBlockOptions & { required?: true }; + } + ): ObjectBlock & { readonly __isRequired: true }; + extend< + ExtendedResultOut extends BlockResultOut, ExtendedParamsOut extends Params = Params, ExtendedParams = Params, ExtendedBlockResult = ResultOut, ExtendedBeforeResultOut = unknown, ExtendedAfterResultOut = unknown, ExtendedErrorResultOut = unknown, - >({ options }: { - options: DescriptBlockOptions< - Context, ExtendedParamsOut, ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams - >; - }) { + >(args: { + options?: DescriptBlockOptions; + }): ObjectBlock; + extend({ options }: { options?: any }): any { return new ObjectBlock({ block: this.extendBlock(this.block), options: this.extendOptions(this.options, options) as typeof options, diff --git a/lib/pipeBlock.ts b/lib/pipeBlock.ts index e9a607f..cfca164 100644 --- a/lib/pipeBlock.ts +++ b/lib/pipeBlock.ts @@ -1,12 +1,12 @@ import CompositeBlock from './compositeBlock'; import { ERROR_ID, createError } from './error'; -import type { DescriptError } from './error'; import type BaseBlock from './block'; import type { BlockResultOut, First, - InferResultFromBlock, + InferResultOrError, InferParamsInFromBlock, + Last, Tail, DescriptBlockOptions, } from './types'; @@ -32,21 +32,8 @@ export type GetPipeBlockParams< PU = GetPipeBlockParamsUnion, > = PU; -type GetPipeBlockResultUnion> = { - 0: never; - 1: First | DescriptError; - 2: First | DescriptError | GetPipeBlockResultUnion>; -}[ T extends [] ? 0 : T extends ((readonly [ any ]) | [ any ]) ? 1 : 2 ]; - -type GetPipeBlockResultMap> = { - [ P in keyof T ]: InferResultFromBlock; -}; - -export type GetPipeBlockResult< - T extends ReadonlyArray, - PA extends ReadonlyArray = GetPipeBlockResultMap, - PU = GetPipeBlockResultUnion, -> = PU; +export type GetPipeBlockResult> = + InferResultOrError>; export type PipeBlockDefinition = { [ P in keyof T ]: T[ P ] extends BaseBlock< @@ -83,21 +70,39 @@ class PipeBlock< > { extend< - // eslint-disable-next-line @typescript-eslint/no-unused-vars - // ExtendedResultOut extends - // BlockResultOut, - // ExtendedCustomBlock extends PipeBlockDefinition, ExtendedParamsOut extends Params = Params, ExtendedParams = Params, ExtendedBlockResult = ResultOut, ExtendedBeforeResultOut = unknown, ExtendedAfterResultOut = unknown, ExtendedErrorResultOut = unknown, - >({ options }: { - options: DescriptBlockOptions< - Context, ExtendedParamsOut, ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams - >; - }) { + >(args: { + options: DescriptBlockOptions & { required: true }; + }): PipeBlock, ExtendedParamsOut, ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams> & { readonly __isRequired: true }; + extend< + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >( + this: PipeBlock & { readonly __isRequired: true }, + args: { + options?: DescriptBlockOptions & { required?: true }; + } + ): PipeBlock, ExtendedParamsOut, ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams> & { readonly __isRequired: true }; + extend< + ExtendedParamsOut extends Params = Params, + ExtendedParams = Params, + ExtendedBlockResult = ResultOut, + ExtendedBeforeResultOut = unknown, + ExtendedAfterResultOut = unknown, + ExtendedErrorResultOut = unknown, + >(args: { + options?: DescriptBlockOptions; + }): PipeBlock, ExtendedParamsOut, ExtendedBlockResult, ExtendedBeforeResultOut, ExtendedAfterResultOut, ExtendedErrorResultOut, ExtendedParams>; + extend({ options }: { options?: any }): any { return new PipeBlock({ block: this.extendBlock(this.block), options: this.extendOptions(this.options, options) as typeof options, diff --git a/lib/types.ts b/lib/types.ts index 4700502..7c92f47 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -104,6 +104,11 @@ export type InferResultOrResultOnce = Result extends BaseBlock< infer BlockResult, infer BeforeResultOut, infer AfterResultOut, infer ErrorResultOut, infer Params > ? ResultOut : Result; +export type InferResultOrError = + T extends { readonly __isRequired: true } + ? InferResultFromBlock + : InferResultFromBlock | DescriptError; + export type InferResultFromBlock = Type extends BaseBlock< // eslint-disable-next-line @typescript-eslint/no-unused-vars infer Context, infer CustomBlock, infer ParamsOut, infer ResultOut, infer IntermediateResult, @@ -111,6 +116,18 @@ export type InferResultFromBlock = Type extends BaseBlock< infer BlockResult, infer BeforeResultOut, infer AfterResultOut, infer ErrorResultOut, infer Params > ? InferResultOrResult : never; +export type DeepResolveResult = + // eslint-disable-next-line @typescript-eslint/no-explicit-any + T extends BaseBlock + ? DeepResolveResult> + : T extends DescriptError + ? DescriptError + : T extends Record + ? { [K in keyof T]: DeepResolveResult } + : T; + +export type DeepInferResultFromBlock = DeepResolveResult>; + export type InferParamsInFromBlock = Type extends BaseBlock< // eslint-disable-next-line @typescript-eslint/no-unused-vars infer Context, infer CustomBlock, infer ParamsOut, infer ResultOut, infer IntermediateResult, @@ -161,6 +178,10 @@ export type Tail = // eslint-disable-next-line @typescript-eslint/no-unused-vars T extends readonly [ infer First, ...infer Rest ] | [ infer First, ...infer Rest ] ? Rest : never; +export type Last = +// eslint-disable-next-line @typescript-eslint/no-unused-vars + T extends readonly [ ...infer _Rest, infer L ] | [ ...infer _Rest, infer L ] ? L : never; + export type Equal = A extends B ? (B extends A ? A : never) : never; export type DepsIds = Array | UntypedId>;