In a situation where I create library that uses another library and I don't want that library to be exposed, is it considered impractical to use different type names for the API?
"Impractical" would be one word for it.
C's rules for type compatibility require structure types not only to have matching member lists, but also to have matching tags or to match in being tagless. Similarly for unions and enums. The rules also require all declarations of the same object or function to specify compatible types for it.*
This means that doing as you describe elicits undefined behavior. In this case, that includes not only undefined runtime behavior but undefined compile time behavior, too.
Given
application ---uses---> library 1 ---uses---> library 2
you have the choice of whether the headers of library 1
expose the data types of library 2
to application
at all. If you choose for them to do, then for structure and union types you also have the choice of whether to expose them as opaque types. But if you want well defined behavior then you do not have the choice of re-tagging library 2
's structure, union, or enum types for application consumption. Different tags yield incompatible types, as C uses the term.
As the project is currently setup (I inherited it), there are two sets
of data types, one maintained by me which mirrors the one used in some
internal (statically linked) libraries. Code is more complex and full
of bugs and I'm asking if my solution would be any better?
I don't see what you think would be gained by continuing to "mirror" the data types of the internal libraries, but with different names. It sounds like that would make your problems worse in several ways, not better.
But you absolutely should come up with a way to avoid duplicating data type definitions. Arrange one way or another for all translation units involved to draw on the same definitions (or none at all) for all data types used. This is the purpose of headers.
Of course, this assumes that you are going to pass objects from the application level through library 1 to library 2, which certainly seems to be what you're describing. And that may be a good plan, but it is not your only alternative.
*This is about the types themselves, not type aliases declared via typedef
.