-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Introduce proper typing for pipelineBreak
- Loading branch information
Showing
8 changed files
with
189 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
interface Pipeline { | ||
<A, R1, R2, R3, R4, R5, R6, R7, R8, R9>( | ||
arg: A, | ||
...functions: PipelineFunctions< | ||
MovingWindow<[A, R1, R2, R3, R4, R5, R6, R7, R8, R9]> | ||
> | ||
): PipelineResult<A, [R1, R2, R3, R4, R5, R6, R7, R8], R9>; | ||
|
||
<A, R1, R2, R3, R4, R5, R6, R7, R8>( | ||
arg: A, | ||
...functions: PipelineFunctions< | ||
MovingWindow<[A, R1, R2, R3, R4, R5, R6, R7, R8]> | ||
> | ||
): PipelineResult<A, [R1, R2, R3, R4, R5, R6, R7], R8>; | ||
|
||
<A, R1, R2, R3, R4, R5, R6, R7>( | ||
arg: A, | ||
...functions: PipelineFunctions< | ||
MovingWindow<[A, R1, R2, R3, R4, R5, R6, R7]> | ||
> | ||
): PipelineResult<A, [R1, R2, R3, R4, R5, R6], R7>; | ||
|
||
<A, R1, R2, R3, R4, R5, R6>( | ||
arg: A, | ||
...functions: PipelineFunctions<MovingWindow<[A, R1, R2, R3, R4, R5, R6]>> | ||
): PipelineResult<A, [R1, R2, R3, R4, R5], R6>; | ||
|
||
<A, R1, R2, R3, R4, R5>( | ||
arg: A, | ||
...functions: PipelineFunctions<MovingWindow<[A, R1, R2, R3, R4, R5]>> | ||
): PipelineResult<A, [R1, R2, R3, R4], R5>; | ||
|
||
<A, R1, R2, R3, R4>( | ||
arg: A, | ||
...functions: PipelineFunctions<MovingWindow<[A, R1, R2, R3, R4]>> | ||
): PipelineResult<A, [R1, R2, R3], R4>; | ||
|
||
<A, R1, R2, R3>( | ||
arg: A, | ||
...functions: PipelineFunctions<MovingWindow<[A, R1, R2, R3]>> | ||
): PipelineResult<A, [R1, R2], R3>; | ||
|
||
<A, R1, R2>( | ||
arg: A, | ||
...functions: PipelineFunctions<MovingWindow<[A, R1, R2]>> | ||
): PipelineResult<A, [R1], R2>; | ||
|
||
<A, R1>( | ||
arg: A, | ||
...functions: PipelineFunctions<MovingWindow<[A, R1]>> | ||
): PipelineResult<A, [], R1>; | ||
} | ||
|
||
type MovingWindow<Types extends [...any[]]> = Types extends [ | ||
infer Left, | ||
infer Right, | ||
...infer Tail, | ||
] | ||
? [[Left, Right], ...MovingWindow<[Right, ...Tail]>] | ||
: []; | ||
|
||
type PipelineFunctions<InputsAndOutputs extends [...any[]]> = | ||
InputsAndOutputs extends [infer Head, ...infer Tail] | ||
? Head extends [infer Input, infer Output] | ||
? [(arg: Argument<Input>) => Output, ...PipelineFunctions<Tail>] | ||
: [] | ||
: []; | ||
|
||
type PipelineResult< | ||
TInput, | ||
TReturnValues extends [...any[]], | ||
TResult, | ||
> = ContainsPromise<[TInput, ...TReturnValues, TResult]> extends true | ||
? Promise<WithCollectivePipelineBreak<TReturnValues, Awaited<TResult>>> | ||
: WithCollectivePipelineBreak<TReturnValues, TResult>; | ||
|
||
export const pipelineBreak: unique symbol; | ||
type Argument<T> = Exclude<Awaited<T>, typeof pipelineBreak>; | ||
|
||
type WithCollectivePipelineBreak< | ||
TReturnValues extends [...any[]], | ||
TResult, | ||
> = ContainsPipelineBreak<[...TReturnValues, TResult]> extends true | ||
? TResult | typeof pipelineBreak | ||
: TResult; | ||
|
||
type ContainsPromise<T extends [...any[]]> = T extends [ | ||
infer Head, | ||
...infer Tail, | ||
] | ||
? Head extends Promise<any> | ||
? true | ||
: ContainsPromise<Tail> | ||
: false; | ||
|
||
type ContainsPipelineBreak<T extends [...any[]]> = T extends [ | ||
infer Head, | ||
...infer Tail, | ||
] | ||
? typeof pipelineBreak extends Head | ||
? true | ||
: ContainsPipelineBreak<Tail> | ||
: false; | ||
|
||
export const pipeline: Pipeline; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
import flow from '../flow/flow'; | ||
import flow, { pipelineBreak } from '../flow/flow'; | ||
|
||
export default (firstArgument, ...args) => flow(...args)(firstArgument); | ||
export { pipelineBreak }; | ||
|
||
export const pipeline = (firstArgument, ...args) => | ||
flow(...args)(firstArgument); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { expectType, expectNotAssignable } from 'tsd'; | ||
import { pipeline, pipelineBreak } from './pipeline'; | ||
|
||
const pipelineResultWithChanceOfBreak = pipeline( | ||
'some-string', | ||
someParameter => { | ||
expectType<string>(someParameter); | ||
|
||
return Math.random() > 0.5 ? pipelineBreak : String('some-other-string'); | ||
}, | ||
someOtherParameter => { | ||
expectType<string>(someOtherParameter); | ||
|
||
return 'some-third-string'; | ||
}, | ||
); | ||
|
||
expectType<string | typeof pipelineBreak>(pipelineResultWithChanceOfBreak); | ||
expectNotAssignable<string>(pipelineResultWithChanceOfBreak); | ||
|
||
const pipelineResultWithNoChanceOfBreak = pipeline( | ||
'some-string', | ||
someParameter => { | ||
expectType<string>(someParameter); | ||
|
||
return 'some-other-string'; | ||
}, | ||
someOtherParameter => { | ||
expectType<string>(someOtherParameter); | ||
|
||
return 'some-third-string'; | ||
}, | ||
); | ||
|
||
expectType<string>(pipelineResultWithNoChanceOfBreak); | ||
expectNotAssignable<typeof pipelineBreak>(pipelineResultWithNoChanceOfBreak); | ||
|
||
const pipelineResultWithAsyncChanceOfBreak = pipeline( | ||
'some-string', | ||
someParameter => { | ||
expectType<string>(someParameter); | ||
|
||
return Math.random() > 0.5 ? pipelineBreak : String('some-other-string'); | ||
}, | ||
async someOtherParameter => { | ||
expectType<string>(someOtherParameter); | ||
|
||
return await 'some-third-string'; | ||
}, | ||
); | ||
|
||
expectType<Promise<string | typeof pipelineBreak>>( | ||
pipelineResultWithAsyncChanceOfBreak, | ||
); | ||
expectNotAssignable<Promise<string>>(pipelineResultWithAsyncChanceOfBreak); | ||
|
||
const pipelineResultWithNoAsyncChanceOfBreak = pipeline( | ||
'some-string', | ||
async someParameter => { | ||
expectType<string>(someParameter); | ||
|
||
return await 'some-other-string'; | ||
}, | ||
someOtherParameter => { | ||
expectType<string>(someOtherParameter); | ||
|
||
return 'some-third-string'; | ||
}, | ||
); | ||
|
||
expectType<Promise<string>>(pipelineResultWithNoAsyncChanceOfBreak); | ||
expectNotAssignable<Promise<typeof pipelineBreak>>( | ||
pipelineResultWithNoAsyncChanceOfBreak, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters