home / skills / git-fg / thecattoolkit / configuring-typescript

configuring-typescript skill

/plugins/sys-nodejs/skills/configuring-typescript

This skill helps you configure modern TypeScript for maximum type safety and fast builds across configs, APIs, and tests.

npx playbooks add skill git-fg/thecattoolkit --skill configuring-typescript

Review the files below or copy the command above to add this skill to your agents.

Files (7)
SKILL.md
3.3 KB
---
name: configuring-typescript
description: "Configures modern TypeScript (4.9+ through 5.x) for maximum type safety with sustainable compile times. Use when designing type-safe configs/maps/APIs, enforcing strictness flags, improving TS build performance (incremental, project references), or setting up separate TS/ESLint configs for tests."
---

# TypeScript Advanced Types

Modern TypeScript playbook for writing code that is **correct**, **ergonomic**, and **fast enough**.

## Quick Reference

| Need | See |
|:-----|-----|
| Modern features (`satisfies`, `const` type params) | [Modern Features](references/modern-features.md) |
| Generics, conditional types, mapped types | [Type-Level Toolbox](references/type-level-toolbox.md) |
| Config objects, event emitters, API clients | [Practical Patterns](references/practical-patterns.md) |
| Test patterns, tsconfig templates | [Tests & Configs](references/tests-configs.md) |
| Compile-time optimization | [Performance Playbook](references/performance-playbook.md) |
| Type testing, PR checklist | [Type Testing](references/type-testing.md) |

## When to Use

Use this skill when:
- Building **type-safe configs/maps/APIs** (feature flags, route tables, event maps)
- Designing **type-safe APIs** (HTTP clients, RPC layers, CLI command maps)
- Enforcing strictness beyond `"strict": true`:
  - `noUncheckedIndexedAccess`
  - `exactOptionalPropertyTypes`
  - `verbatimModuleSyntax`
- Improving compile times (incremental builds, project references)
- Setting up separate TS/ESLint configs for tests



## Default Workflow

1. **Start with data shape and ownership** — Is value internally constructed (safe) or external input (unsafe)?
2. **Choose the lightest typing tool** — `satisfies` for configs, mapped types for transformations, `infer` for function inference
3. **Lock strictness and hygiene** — Enable `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, consider `verbatimModuleSyntax`
4. **Keep builds fast** — Enable `incremental`, use project references in monorepos, measure with `--extendedDiagnostics`
5. **Tests: strict where matters, pragmatic where not** — Separate `tsconfig.test.json`, ESLint overrides for test files only

## Key Highlights

### `satisfies` — Use Aggressively
Validates object shape without losing literal inference or widening to `string`/`number`.

```ts
type AppConfig = {
  env: "dev" | "prod";
  apiBaseUrl: string;
  retries: number;
};

export const config = {
  env: "dev",
  apiBaseUrl: "https://api.example.com",
  retries: 3,
} satisfies AppConfig;
// config.env is "dev" (literal), not "dev" | "prod"
```

### Strictness Beyond `"strict": true`

**`noUncheckedIndexedAccess`** — Adds `undefined` to indexed access:
```ts
const dict: Record<string, { id: string }> = {};
const x = dict["missing"]; // { id: string } | undefined
```

**`exactOptionalPropertyTypes`** — Optional ≠ undefined:
```ts
type UserPrefs = { theme?: "dark" | "light" };
const prefs: UserPrefs = {};
prefs.theme = "dark";     // ok
// prefs.theme = undefined; // error
```

**`verbatimModuleSyntax`** — Module hygiene:
```ts
import type { User } from "./types";     // type-only
import { createUser } from "./runtime"; // runtime (kept in output)
```

## Resources

See [references/](references/) for detailed guides on each topic.

Overview

This skill configures modern TypeScript (4.9+ through 5.x) for maximum type safety while keeping compile times practical. It provides a playbook of compiler flags, typing patterns, and build techniques to make configs, APIs, and test code robust and maintainable. The goal is predictable types, clear ownership of data, and fast incremental builds.

How this skill works

The skill inspects intended data ownership (internal vs external) and recommends the lightest typing tool that preserves inference (for example, using satisfies for config objects). It enforces advanced strictness flags such as noUncheckedIndexedAccess, exactOptionalPropertyTypes, and verbatimModuleSyntax to close common holes. It also suggests build settings—incremental, project references, and diagnostics—to keep compile times sustainable and separate tsconfig/ESLint behavior for tests.

When to use it

  • When designing type-safe configuration objects, route maps, feature flags, or event maps
  • When building typed HTTP/RPC clients or CLI command maps that must preserve literal inference
  • When you need stricter guarantees than "strict": true (e.g., indexed access safety, exact optional properties)
  • When optimizing TypeScript build performance in monorepos or large codebases
  • When you want pragmatic test typing with separate tsconfig/ESLint overrides

Best practices

  • Start by deciding data ownership: mark external input as unsafe and validate early
  • Prefer the lightest tool that achieves the intent: use satisfies to retain literals, not unnecessary generics
  • Enable noUncheckedIndexedAccess and exactOptionalPropertyTypes to make missing fields explicit
  • Use incremental builds and project references for large projects; measure with --extendedDiagnostics
  • Keep tests strict where it matters and relax only with dedicated tsconfig.test.json and targeted ESLint overrides

Example use cases

  • Authoring a central app config that preserves literal types for environment keys using satisfies
  • Implementing a typed event-emitter map where subscribers require exact payload shapes
  • Creating a typed HTTP client layer that enforces input/output contracts and narrows responses
  • Speeding up CI builds in a monorepo with project references and incremental compilation
  • Keeping test files pragmatic by using a separate tsconfig and ESLint overrides for mocked code

FAQ

Why use satisfies instead of declaring the object type?

satisfies validates shape while preserving literal inference and avoiding broad widening to string/number, giving better ergonomics and stricter checking.

Will strict flags slow down compilation?

Some checks add cost, but combining strict flags with incremental builds, project references, and targeted diagnostics keeps compile times practical.

When should I enable exactOptionalPropertyTypes?

Enable it when you want optional properties to be distinct from allowing undefined, which prevents accidental undefined assignments and clarifies intent.