Los genéricos dejan de ser realmente útiles cuando solo sirven para repetir T. Empiezan a escalar cuando modelan restricciones y decisiones del dominio.

Patrón base

type ApiResult<TData, TError = Error> =
  | { ok: true; data: TData }
  | { ok: false; error: TError };

type UnwrapResult<T> = T extends ApiResult<infer TData, unknown> ? TData : never;

Con este enfoque, el tipo también comunica el contrato de errores y reduce chequeos ambiguos.

Regla práctica

Si un genérico no mejora seguridad, reuso o legibilidad, probablemente solo agrega complejidad.