diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2025-11-04 20:53:14 -0800 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2025-11-04 20:53:30 -0800 |
| commit | b8fd8f0672c289ff43e501f430b76de1c7b0440a (patch) | |
| tree | 57cf1f50700649189406ccfd50b7c430d5547c3c /src | |
| parent | f9f52cd6081036fa98e86a537c925f7a8e924df7 (diff) | |
constrained args for createFn
Diffstat (limited to 'src')
| -rw-r--r-- | src/lang/ks-lang/index.ts | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/src/lang/ks-lang/index.ts b/src/lang/ks-lang/index.ts index c9c7405..e5a78b9 100644 --- a/src/lang/ks-lang/index.ts +++ b/src/lang/ks-lang/index.ts @@ -14,19 +14,29 @@ export type TransformArgs<Args extends readonly ASTNode[]> = { [Idx in keyof Args]: any; }; -export const createFn = <Program extends string>( - program: Program -): Evaluate<Parse<Lex<Program>>> extends [infer ProgramFn extends FnPrim] - ? <const Args extends TransformArgs<ProgramFn["args"]>>( - ...args: Args - ) => CallFn<ProgramFn, Args, EmptyStackFrame> - : EvalError<"Cannot create a function from a program that does not eval to a function"> => { - const [programFn] = evaluate(parse(lex(program))) as Array<FnPrim>; - if (!programFn.fn) { - throw new Error( - "Cannot create a function from a program that does not eval to a function" - ); - } +export type AssertArgs< + Args extends readonly ASTNode[], + ArgsConstraint extends readonly any[] +> = TransformArgs<Args> extends ArgsConstraint ? ArgsConstraint : never; - return ((...args: any[]) => callFn(programFn, args, emptyStackFrame)) as any; -}; +export const createFn = + <ArgsConstraint extends any[]>() => + <Program extends string>( + program: Program + ): Evaluate<Parse<Lex<Program>>> extends [infer ProgramFn extends FnPrim] + ? TransformArgs<ProgramFn["args"]> extends ArgsConstraint + ? <const Args extends ArgsConstraint>( + ...args: Args + ) => CallFn<ProgramFn, Args, EmptyStackFrame> + : EvalError<`Program's args do not extend args constraint`> + : EvalError<"Cannot create a function from a program that does not eval to a function"> => { + const [programFn] = evaluate(parse(lex(program))) as Array<FnPrim>; + if (!programFn.fn) { + throw new Error( + "Cannot create a function from a program that does not eval to a function" + ); + } + + return ((...args: any[]) => + callFn(programFn, args, emptyStackFrame)) as any; + }; |
