Skip to content

Instantly share code, notes, and snippets.

@KrisKnez
Created February 15, 2023 18:19
Show Gist options
  • Select an option

  • Save KrisKnez/28a464b412ca6d59765e5e6e87503e92 to your computer and use it in GitHub Desktop.

Select an option

Save KrisKnez/28a464b412ca6d59765e5e6e87503e92 to your computer and use it in GitHub Desktop.
A Function That Executes An Array Of Function Call Instructions In Typescript Using A Helper Function That Generates A Branded Function Call Instruction
export type InspectRulesArgs<T extends (...args: any) => any> =
| T[]
| [T, ...Parameters<T>][];
export type InspectRulesResult = "pending" | "approved" | "denied";
declare const brand: unique symbol;
type Branded<T, Brand extends string> = T & {
[brand]: Brand;
}
const callTuple = <Fn extends (...args: any[]) => InspectRulesResult>(
fn: Fn,
...args: Parameters<Fn>
) => [fn, ...args] as const as Branded<readonly [Fn, ...Parameters<Fn>], "withHelper">;
const inspectRules = (
...rules: ReadonlyArray<
| (() => InspectRulesResult)
| Branded<readonly [(...args: any[]) => InspectRulesResult, ...any[]], "withHelper">
>
): InspectRulesResult => {
const pendingRules = rules.map((rule) => {
if (typeof rule === "function") {
return rule();
} else {
const [func, ...args] = rule;
return func(...args);
}
});
if (pendingRules.includes("denied")) {
return "denied";
}
if (pendingRules.includes("pending")) {
return "pending";
}
return "approved";
};
inspectRules(
() => "pending" as const,
// @ts-expect-error helper not used
[(foo: string) => "approved" as const, ""] as const,
callTuple((foo: string) => "approved" as const, ""),
// @ts-expect-error wrong arg
callTuple((foo: number) => "approved" as const, ""),
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment