TypeScript snippets

Keep your team's TypeScript snippets in one base.

debounce, a Result type, the typed fetch wrapper — every TypeScript codebase grows the same utilities, and every new repo rewrites them slightly differently until nobody knows which version is right. The-Snip gives your team one reviewed home for them: searchable snippets with VS Code-grade highlighting, tags and collections per domain, and Markdown docs that explain the why next to the code. Your agents read the same base over REST and MCP — Cursor or Claude Code finds the canonical debounce instead of generating a fourth variant — and anything they file back waits in review until a human approves it.

TypeScript snippets worth keeping

Debounce

export function debounce<A extends unknown[]>(fn: (...a: A) => void, ms = 300) {
  let t: ReturnType<typeof setTimeout>;
  return (...a: A) => {
    clearTimeout(t);
    t = setTimeout(() => fn(...a), ms);
  };
}

Delay a call until input settles — the classic search-box helper. Keeping one canonical, typed version ends the era of five slightly-different debounces across the monorepo.

Result type

export type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E };

export const ok = <T>(value: T): Result<T> => ({ ok: true, value });
export const err = <E>(error: E): Result<never, E> => ({ ok: false, error });

Return errors as values instead of throwing across boundaries. Callers are forced to handle the failure path at compile time — no forgotten try/catch three layers up.

Typed fetch JSON

export async function getJson<T>(url: string, init?: RequestInit): Promise<T> {
  const res = await fetch(url, init);
  if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
  return res.json() as Promise<T>;
}

One wrapper that throws on non-2xx and types the body. Pair it with the Result type above at service boundaries and error handling stays honest end to end.

Group by key

export function groupBy<T, K extends PropertyKey>(items: T[], key: (t: T) => K) {
  return items.reduce((acc, item) => {
    (acc[key(item)] ??= []).push(item);
    return acc;
  }, {} as Record<K, T[]>);
}

Bucket an array without a utility library. The ??= assignment keeps it one pass and the Record type keeps the keys honest.

Promise with timeout

export async function withTimeout<T>(p: Promise<T>, ms: number): Promise<T> {
  let t: ReturnType<typeof setTimeout> | undefined;
  const timeout = new Promise<never>((_, reject) => {
    t = setTimeout(() => reject(new Error(`Timed out after ${ms}ms`)), ms);
  });
  try {
    return await Promise.race([p, timeout]);
  } finally {
    clearTimeout(t);
  }
}

Race any promise against a deadline and clean up the timer either way. Wrap third-party SDK calls with it so one slow dependency can't hang a request handler.

Questions, answered.

Can I keep both a snippet and its sample output?

Yes — every snippet can carry a sample-output block, so a teammate sees what it does before running it. For type-level utilities, teams often paste the compiler error the snippet prevents.

Do agents get the TypeScript base too?

Yes, over REST or the hosted MCP server — reads are free on every plan; agent writes need the one Pro & Team plan ($8/user/month). Agents call search_base before writing utility code and propose new snippets with create_snippet; everything they write lands in review.

How do teams keep utilities organized?

Collections per domain (http, react, node, testing), tags for finer cuts, and favorites for the daily drivers. Weighted search means a title match on "debounce" beats a body mention every time — the / shortcut gets you there without leaving the keyboard.

Does it handle JavaScript and TSX as well?

Yes — JavaScript, TypeScript and 35+ other languages, highlighted server-side with VS Code's own grammars. Generics, JSX and template literals all render correctly in both light and dark themes.

Can I export everything if we leave?

Yes — export your base as .md or .json on the paid plan. Snippets, saved API calls and docs come out as plain, portable files. No lock-in is a design goal, not a promise buried in a FAQ.

Start your base — free.

Free: 25 items, no card. Pro & Team: $8/user/mo — unlimited items, REST API, review workflow, and the hosted MCP server.