# Generic type constraints applied

- **Pattern:** `ab-002155` (`code-quality-essentials.organization.generic-constraints`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002155
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002155)

## Why it matters

An unconstrained generic `<T>` is effectively `<T extends unknown>` — it accepts any value, and TypeScript cannot enforce meaningful relationships between `T` and the function's behavior. The symptom is forced casts inside the generic body: if you need `(item as any).id`, the generic is not constrained correctly. ISO 25010:2011 §6.5.4 classifies this as a type-safety defect. Unconstrained generics in utility code are particularly insidious because they look safe from the outside while silently bypassing type checks inside.

## Severity rationale

Medium because unconstrained generics defeat the purpose of generic typing — they provide an API that looks type-safe but requires internal casts to work, masking real type errors.

## Remediation

Add `extends` constraints to generics that access specific properties or operate on values with known shapes. This eliminates the internal casts that unconstrained generics require:

```typescript
// Bad: unconstrained T, forced cast to access 'id'
function findById<T>(items: T[], id: string): T | undefined {
  return items.find((item) => (item as any).id === id)
}

// Good: constraint ensures T has 'id'
function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
  return items.find((item) => item.id === id)  // no cast needed
}

// Good: keyof constraint for property access
function getProperty<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key]
}
```

## Detection

- **ID:** `generic-constraints`
- **Severity:** `medium`
- **What to look for:** Search source files for generic type parameters (`<T>`, `<K>`, `<V>`). For each usage, check whether the generic is constrained with an `extends` clause. An unconstrained `<T>` is effectively `<T extends unknown>`, meaning the generic function accepts any value and TypeScript cannot enforce meaningful type relationships. Well-constrained generics look like: `<T extends object>`, `<T extends Record<string, unknown>>`, `<K extends keyof T>`, `<T extends BaseModel>`. Look especially at utility functions, API response handlers, data transformation functions, and React component props that use generics. Unconstrained generics in utility code are a signal the developer was trying to avoid writing a proper type.
- **Pass criteria:** Enumerate all relevant code locations. Generic functions use `extends` constraints that accurately describe what types are accepted. Unconstrained `T` only appears in utility types where any value is genuinely valid (e.g., identity function) with at least 1 verified location.
- **Fail criteria:** Generics used liberally without constraints, effectively allowing any value and defeating the purpose of typing.
- **Skip (N/A) when:** Project has no generics used anywhere (no generic functions, no generic types).
- **Detail on fail:** `"Unconstrained generics found in utility functions; T used without extends clause where a constraint would improve type safety"`
- **Remediation:** Add constraints to generics that accept values used in specific ways:

  ```typescript
  // Bad: unconstrained T, no guarantee T has an 'id' field
  function findById<T>(items: T[], id: string): T | undefined {
    return items.find((item) => (item as any).id === id)  // forced cast
  }

  // Good: constraint ensures T has 'id'
  function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
    return items.find((item) => item.id === id)  // no cast needed
  }

  // Good: keyof constraint for property access
  function getProperty<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
    return obj[key]
  }
  ```

## External references

- iso-25010 maintainability.modifiability

Taxons: code-quality

HTML version: https://auditbuffet.com/patterns/ab-002155
