diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..b45cce9 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,24 @@ +type CPSFn< + Callbacks extends Array<(...args: unknown[]) => void> +> = (...args: Callbacks) => void + +type ChainFns< + FromCallbacks extends Array<(...args: unknown[]) => void>, + ToCallbacks extends Array<(...args: unknown[]) => void>, +> = { + [T in keyof FromCallbacks]?: ((...args: Parameters) => CPSFn) | undefined +} + +type CPS< + Callbacks extends Array<(...args: unknown[]) => void> +> = CPSFn & { + chain< + ToCallbacks extends Array<(...args: unknown[]) => void> + >(...fns: ChainFns): CPS +} + +declare function CPS< + Callbacks extends Array<(...args: unknown[]) => void> +>(fn: CPSFn): CPS + +export { CPS, CPSFn } diff --git a/package.json b/package.json index a4ded3b..a637d06 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,10 @@ "name": "cpsfy", "description": "Tiny goodies for Continuation-Passing-Style functions", "main": "index.js", + "types": "index.d.ts", "files": [ "index.js", + "index.d.ts", "utils.js" ], "repository": "https://github.com/dmitriz/cpsfy.git", diff --git a/type-test/chain.ts b/type-test/chain.ts new file mode 100644 index 0000000..34c322d --- /dev/null +++ b/type-test/chain.ts @@ -0,0 +1,35 @@ +import { CPS, type CPSFn } from "../index" + +const cpsFn: CPSFn<[ + (a: number, b: number) => void, + (a: number, b: string) => void, +]> = (cb1, cb2) => { cb1(2,3); cb2(7, "bar") } + +const f1 = (x: number, y: number): CPSFn<[ + (x: number, y?: string) => void, + (x: number) => void, +]> => (cb1, cb2) => { cb1(x+y); cb2(x-y) } + +const f2 = (x: number, y: string): CPSFn<[ + (x: number, y?: string) => void, +]> => (cb1) => { cb1(x, y) } + +const chainOneWay = CPS(cpsFn).chain(f1, f2) + +const chainSecondWay = CPS(cpsFn).chain<[ + (x: number, y?: string) => void, + (x: number) => void, +]>( + (x, y) => (cb1, cb2) => { cb1(x+y); cb2(x-y) }, + (x, y) => (cb1) => { cb1(x, y) } +) + +const chainThirdWay = CPS(cpsFn).chain( + (x: number, y: number) => ( + cb1: (x: number, y?: string) => void, + cb2: (x: number) => void + ) => { cb1(x+y); cb2(x-y) }, + (x: number, y: string) => ( + cb1: (x: number, y?: string) => void, + ) => { cb1(x, y) } +)