I strongly recommend DTOs, and we have been using DTOs with this Typewriter extension for Visual Studio to keep the .ts files in sync with the .cs files.
Maybe you could do something similar.
https://frhagn.github.io/Typewriter/
The Angular front end uses the .ts version and the C# backend uses the .cs version.
You can edit the .tst (typescript template file) in order to pull off a lot of customization if you need any differences between your .ts and .cs version.
This is the best pattern I've came up with below, which allows us to nest Enums and other Dto classes:
${
// Enable extension methods by adding using Typewriter.Extensions.*
using Typewriter.Extensions.Types;
string TypeWithNoArray(Type t) => t.Name.TrimEnd('[', ']');
}
/* DO NOT EDIT ANY .TS FILES WITH THIS COMMENT
THESE .TS FILES ARE GENERATED BY A CORRESPONDING .CS FILE AND A .TST FILE
BY USING THE TYPEWRITER EXTENSION:
https://frhagn.github.io/Typewriter */
$Classes(*Dto*)[
$Properties(x => !x.Type.IsPrimitive || x.Type.IsEnum)[$Type[import { $TypeWithNoArray } from './$TypeWithNoArray';
]]
export class $Name {
$Properties[public $name: $Type = $Type[$Default];
]$BaseClass[$Properties[public $name: $Type = $Type[$Default];]]
}
]
$Enums(*Dto*)[
export enum $Name {$Values[
$name = $Value][,]
}
]