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.