import type { BaseRoot, IntersectionNode } from "@ark/schema"; import { Callable, type applyElementLabels, type conform, type Fn, type get } from "@ark/util"; import type { distill } from "./attributes.ts"; import type { type } from "./keywords/keywords.ts"; import type { validateInnerDefinition } from "./parser/definition.ts"; import type { inferTupleLiteral, validateTupleLiteral } from "./parser/tupleLiteral.ts"; import type { InternalScope, Scope } from "./scope.ts"; import type { Type } from "./type.ts"; export type BaseFnParser<$ = {}> = , returnT = args extends readonly [...unknown[], ":", infer returnDef] ? type.infer : unknown>(...args: { [i in keyof args]: conform, i>>; }) => ) => distill.In, externalSignature extends Fn = (...args: applyElementLabels, Parameters>) => args extends readonly [...unknown[], ":", unknown] ? distill.Out : ReturnType>(implementation: internalSignature) => TypedFn; export interface FnParser<$ = {}> extends BaseFnParser<$> { /** * The {@link Scope} in which definitions passed to this function will be parsed. */ $: Scope<$>; /** * An alias of `fn` with no type-level validation or inference. * * Useful when wrapping `fn` or using it to parse a dynamic definition. */ raw: RawFnParser; } export type RawFnParser = (...args: unknown[]) => (...args: unknown[]) => unknown; export declare class InternalFnParser extends Callable<(...args: unknown[]) => Fn> { constructor($: InternalScope); } export declare namespace TypedFn { type meta = { introspectableReturn?: true; }; } export interface TypedFn extends Callable { expression: string; params: signature extends Fn ? Type : never; returns: Type : unknown, $>; } export declare class InternalTypedFn extends Callable<(...args: unknown[]) => unknown> { raw: Fn; params: IntersectionNode; returns: BaseRoot; expression: string; constructor(raw: Fn, params: IntersectionNode, returns: BaseRoot); } export declare namespace Return { interface introspectable { introspectableReturn: true; } } type validateFnArgs = args extends readonly unknown[] ? args extends readonly [...infer paramDefs, ":", infer returnDef] ? readonly [ ...validateFnParamDefs, ":", type.validate ] : validateFnParamDefs : never; type validateFnParamDefs = paramDefs extends validateTupleLiteral ? paramDefs : paramDefs extends { [i in keyof paramDefs]: paramDefs[i] extends "..." ? paramDefs[i] : validateInnerDefinition; } ? validateTupleLiteral : { [i in keyof paramDefs]: validateInnerDefinition; }; export declare const badFnReturnTypeMessage = "\":\" must be followed by exactly one return type e.g:\nfn(\"string\", \":\", \"number\")(s => s.length)"; export {};