This is where OpenAPI/Swagger shines, we use C# backends and with NSwag (built in now also I think) you get an online API-spec directly from the controller (and types) of the C# code.
Only extra step is running a tool to download the swagger and produce auto-generated typescript definitions, otherwise the workflow is the same as shared code (Some projects are typescript on both ends but C# gives a ton of other benefits for backends).
My recent experience with NSwag was really bad... It could only handle the simplest of jsonschema. We were trying to connect with a typescript API that had heavy use of union and product types. Maybe the problem was just that C# doesn't support algebraic typings?
Yeah, the C++/Java/C# family of type systems have obvious holes in them. There are various hacks/implementations for them but since they're not in the core they're not really expected to be supported by random tools either.
Like mentioned, our regular pipe is C# producer (server) and TS consumer (client). Consuming services authored in Java,etc is usually not a problem either but the TS system definetly has a bunch of more cases that aren't easily mapped.
This is what we do. We use kiota to generate clients within other C# services, and orval to generate a client in the frontend. We also run some basic checks against the openapi definition in branch, to detect breaking changes and whatnot.
Only extra step is running a tool to download the swagger and produce auto-generated typescript definitions, otherwise the workflow is the same as shared code (Some projects are typescript on both ends but C# gives a ton of other benefits for backends).