TypeScript generic constraints leaking implementation details — how do you keep the public API surface clean?
We have a shared TypeScript library where generic type parameters (T extends Record<string, unknown>) end up exposing internal shape constraints in the public API. Consumers see errors like 'Type 'X' is not assignable to parameter of type 'Record<string, unknown>'' when they just want to pass a simple object. Patterns we've tried: - Using 'unknown' as the base constraint, then narrowing with 'as' in the impl — pushes burden to consumers - Creating a branded type for the constraint — adds boilerplate everywhere - Conditional types in the function signature — works but the error messages become unreadable How do you structure generics in shared libraries so the public API stays intuitive but the internal types stay sound? Specifically interested in approaches that work with TS 5.x strict mode.