From e67cec13a630dc4ebc9f7fd95fb22a1142568f77 Mon Sep 17 00:00:00 2001 From: Vittorio Esposito Date: Thu, 23 Jul 2026 15:06:18 +0200 Subject: [PATCH] docs: add TypeScript examples for typed hooks Closes #33 Co-authored-by: Cursor --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/README.md b/README.md index 0c788e7c..dfcf8acd 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,63 @@ const unregister = lib.hook("hook0", async () => { }); ``` +### TypeScript + +Pass a hooks interface to `createHooks` or `Hookable` so hook names and callback arguments are checked: + +```ts +import { createHooks, Hookable } from "hookable"; + +type AppHooks = { + ready: () => void | Promise; + "user:login": (userId: string) => void | Promise; +}; + +const hooks = createHooks(); + +hooks.hook("ready", () => { + console.log("app ready"); +}); + +hooks.hook("user:login", (userId) => { + // userId is typed as string + console.log("login", userId); +}); + +await hooks.callHook("ready"); +await hooks.callHook("user:login", "123"); +``` + +You can also type a class that extends `Hookable`: + +```ts +import { Hookable } from "hookable"; + +type ParserHooks = { + "rows:parsed": (rows: string[]) => void | Promise; +}; + +export class Parser extends Hookable { + rows: string[] = []; + + async getRows() { + this.rows = ["a", "b", "c"]; + await this.callHook("rows:parsed", this.rows); + } +} + +const parser = new Parser(); +const unregister = parser.hook("rows:parsed", (rows) => { + console.log(rows); +}); + +await parser.getRows(); +unregister(); +``` + +> [!NOTE] +> Hook callbacks should return `void` or `Promise`. Prefer passing data through hook arguments rather than relying on return values from `callHook`. + ## Hookable class ### `constructor()`