Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/typescript-examples/array.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-console */
import * as de from '../../lib';
import { blockNeedsA, blockNeedsB, ParamsA, ParamsAB } from './shared';

// --------------------------------------------------------------------------------------------------------------- //

Expand Down Expand Up @@ -155,3 +156,28 @@ de.run(bfn3, {
.then((result) => {
console.log(result[ 0 ], result[ 1 ]);
});

// --------------------------------------------------------------------------------------------------------------- //
// Тут проверяем, что есть ошибка при несовпадении параметров и нету ошибки при валидных параметрах вложенных блоков
// @ts-expect-error тут должна быть DescriptParamsError
de.func({
block: ({ params }: { params: ParamsA }) => {
void params;

return de.array({
block: [ blockNeedsA, blockNeedsB ],
});
},
});

de.func({
block: ({ params }: { params: ParamsAB }) => {
void params;

return de.array({
block: [ blockNeedsA, blockNeedsB ],
});
},
});

// --------------------------------------------------------------------------------------------------------------- //
26 changes: 26 additions & 0 deletions docs/typescript-examples/first.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-console */
import * as de from '../../lib';
import { blockNeedsA, blockNeedsB, ParamsA, ParamsAB } from './shared';

// --------------------------------------------------------------------------------------------------------------- //

Expand Down Expand Up @@ -164,3 +165,28 @@ de.run(bfn3, {
.then((result) => {
console.log(result);
});

// --------------------------------------------------------------------------------------------------------------- //
// Тут проверяем, что есть ошибка при несовпадении параметров и нету ошибки при валидных параметрах вложенных блоков
// @ts-expect-error тут должна быть DescriptParamsError
de.func({
block: ({ params }: { params: ParamsA }) => {
void params;

return de.first({
block: [ blockNeedsA, blockNeedsB ],
});
},
});

de.func({
block: ({ params }: { params: ParamsAB }) => {
void params;

return de.first({
block: [ blockNeedsA, blockNeedsB ],
});
},
});

// --------------------------------------------------------------------------------------------------------------- //
25 changes: 25 additions & 0 deletions docs/typescript-examples/func.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-console */
import * as de from '../../lib';
import { blockNeedsA, blockNeedsAB, blockNeedsB, ParamsA, ParamsAB } from './shared';

interface ParamsIn1 {
id: string;
Expand Down Expand Up @@ -126,3 +127,27 @@ de.run(block4, {
.then((result) => {
console.log(result);
});

// --------------------------------------------------------------------------------------------------------------- //
// Тут проверяем, что есть ошибка при несовпадении параметров и нету ошибки при валидных параметрах вложенных блоков
// @ts-expect-error тут должна быть DescriptParamsError
de.func({
block: ({ params }: { params: ParamsA }) =>
params.a === 'special' ? blockNeedsA : blockNeedsB,
});

de.func({
block: ({ params }: { params: ParamsAB }) =>
params.a === 'special' ? blockNeedsA : blockNeedsB,
});

de.run(blockNeedsAB, {
params: { a: 'hello', b: 42 },
});

de.run(blockNeedsAB, {
// @ts-expect-error тут должна быть ошибка 'b' is declared here.
params: { a: 'hello' },
});

// --------------------------------------------------------------------------------------------------------------- //
45 changes: 28 additions & 17 deletions docs/typescript-examples/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import * as de from '../../lib';
import type { DescriptHttpBlockResult, InferParamsInFromBlock } from '../../lib/types';
import { blockNeedsA, blockNeedsB, ParamsA, ParamsAB } from './shared';

// --------------------------------------------------------------------------------------------------------------- //

Expand Down Expand Up @@ -96,7 +97,7 @@ const block2 = de.http({

const block2Func = de.func({
// eslint-disable-next-line @typescript-eslint/no-unused-vars
block: ({ params }: { params: InferParamsInFromBlock<typeof block1> & { p1: number } }) => block2,
block: ({ params }: { params: InferParamsInFromBlock<typeof block2> & { p1: number } }) => block2,
// block: () => block2,
options: {
after: ({ result }) => {
Expand All @@ -111,11 +112,8 @@ const block2Func = de.func({

de.run(block2Func, {
params: {
id1: '67890',
p1: 1,
payload: {
card: {},
},
id2: 578923,
},
})
.then((result) => {
Expand Down Expand Up @@ -166,12 +164,8 @@ const block3 = de.object({

de.run(block3, {
params: {
id1: '12345',
id2: 67890,
p1: 1,
payload: {
card: {},
},
},
})
.then((result) => {
Expand Down Expand Up @@ -230,12 +224,8 @@ const block5 = block3.extend({

de.run(block4, {
params: {
id1: '12345',
id2: 67890,
p1: 1,
payload: {
card: {},
},
},
})
.then((result) => {
Expand All @@ -244,14 +234,35 @@ de.run(block4, {

de.run(block5, {
params: {
id1: '12345',
id2: 67890,
p1: 1,
payload: {
card: {},
},
},
})
.then((result) => {
console.log(result);
});

// --------------------------------------------------------------------------------------------------------------- //
// Тут проверяем, что есть ошибка при несовпадении параметров и нету ошибки при валидных параметрах вложенных блоков
// @ts-expect-error тут должна быть DescriptParamsError
de.func({
block: ({ params }: { params: ParamsA }) => {
void params;

return de.object({
block: { blockNeedsA, blockNeedsB },
});
},
});

de.func({
block: ({ params }: { params: ParamsAB }) => {
void params;

return de.object({
block: { blockNeedsA, blockNeedsB },
});
},
});

// --------------------------------------------------------------------------------------------------------------- //
26 changes: 26 additions & 0 deletions docs/typescript-examples/pipe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable no-console */
import * as de from '../../lib';
import { blockNeedsA, blockNeedsB, ParamsA, ParamsAB } from './shared';

// --------------------------------------------------------------------------------------------------------------- //

Expand Down Expand Up @@ -164,3 +165,28 @@ de.run(bfn3, {
.then((result) => {
console.log(result);
});

// --------------------------------------------------------------------------------------------------------------- //
// Тут проверяем, что есть ошибка при несовпадении параметров и нету ошибки при валидных параметрах вложенных блоков
// @ts-expect-error тут должна быть DescriptParamsError
de.func({
block: ({ params }: { params: ParamsA }) => {
void params;

return de.pipe({
block: [ blockNeedsA, blockNeedsB ],
});
},
});

de.func({
block: ({ params }: { params: ParamsAB }) => {
void params;

return de.pipe({
block: [ blockNeedsA, blockNeedsB ],
});
},
});

// --------------------------------------------------------------------------------------------------------------- //
32 changes: 32 additions & 0 deletions docs/typescript-examples/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import * as de from '../../lib';

export interface ParamsA {
a: string;
}

export interface ParamsB {
b: number;
}

export interface ParamsAB {
a: string;
b: number;
}

export const blockNeedsA = de.http({
block: {
pathname: ({ params }: { params: ParamsA }) => `/a/${ params.a }`,
},
});

export const blockNeedsB = de.http({
block: {
pathname: ({ params }: { params: ParamsB }) => `/b/${ params.b }`,
},
});

export const blockNeedsAB = de.http({
block: {
pathname: ({ params }: { params: ParamsAB }) => `/b/${ params.b }/${ params.a }`,
},
});
11 changes: 6 additions & 5 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import type {
InferBlock,
InferHttpBlock,
InferResultOrResult,
ExtractBadNestedParams,
} from './types';
import type BaseBlock from './block';
import type { DescriptHttpBlockDescription, DescriptHttpBlockQuery, DescriptHttpBlockQueryValue } from './httpBlock';
Expand All @@ -51,7 +52,7 @@ const func = function<
options?: DescriptBlockOptions<
Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params
>;
}) {
} & ([ ExtractBadNestedParams<BlockResult, ParamsOut> ] extends [ never ] ? unknown : ExtractBadNestedParams<BlockResult, ParamsOut>)) {
return new FunctionBlock<
Context, ParamsOut, BlockResult, ResultOut, BeforeResultOut, AfterResultOut, ErrorResultOut, Params
>({ block, options });
Expand All @@ -68,7 +69,7 @@ const array = function<
Params = GetArrayBlockParams<Block>,
>({ block, options }: {
block: ArrayBlockDefinition<Block>;
options?: DescriptBlockOptions<Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
}) {
return new ArrayBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>({ block, options });
};
Expand All @@ -85,7 +86,7 @@ const object = function<
Params = GetObjectBlockParams<Blocks>,
>({ block, options }: {
block?: ObjectBlockDefinition<Blocks>;
options?: DescriptBlockOptions<Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
} = {}) {
return new ObjectBlock<Context, Blocks, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>({ block, options });
};
Expand Down Expand Up @@ -121,7 +122,7 @@ const first = function<
Params = GetFirstBlockParams<Block>,
>({ block, options }: {
block: FirstBlockDefinition<Block>;
options?: DescriptBlockOptions<Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
}) {
return new FirstBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>({ block, options });
};
Expand All @@ -138,7 +139,7 @@ const pipe = function<
Params = GetPipeBlockParams<Block>,
>({ block, options }: {
block: PipeBlockDefinition<Block>;
options?: DescriptBlockOptions<Context, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
options?: DescriptBlockOptions<Context, NoInfer<ParamsOut>, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>;
}) {
return new PipeBlock<Context, Block, ResultOut, ParamsOut, BlockResult, BeforeResultOut, AfterResultOut, ErrorResultOut, Params>({ block, options });
};
Expand Down
21 changes: 21 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ export type NonNullableObject<T extends Record<string, unknown>> = {
[P in keyof T]: Exclude<T[P], undefined>;
};

export type DescriptParamsError<Required, Available> = {
readonly __descriptError: 'NESTED_BLOCK_PARAMS_INCOMPATIBLE';
readonly __requiredParams: Required;
readonly __availableParams: Available;
readonly __fix: 'Add options.params to transform parent params into the required shape';
};

// Extracts DescriptParamsError for any block in T whose Params are not satisfied by the available Params.
// Returns never when all blocks are compatible (no constraint added to the call site).
export type ExtractBadNestedParams<T, Params> =
[ unknown ] extends [ Params ]
? never
// eslint-disable-next-line @typescript-eslint/no-explicit-any
: T extends BaseBlock<any, any, any, any, any, any, any, any, any, infer BParams>
? unknown extends BParams
? never
: [ Params ] extends [ BParams ]
? never
: DescriptParamsError<BParams, Params>
: never;

export type DescriptJSON =
boolean |
number |
Expand Down
Loading