TypeScriptRequestCommandsGenerator 0.9.45
See the version list below for details.
dotnet add package TypeScriptRequestCommandsGenerator --version 0.9.45
NuGet\Install-Package TypeScriptRequestCommandsGenerator -Version 0.9.45
<PackageReference Include="TypeScriptRequestCommandsGenerator" Version="0.9.45" />
<PackageVersion Include="TypeScriptRequestCommandsGenerator" Version="0.9.45" />
<PackageReference Include="TypeScriptRequestCommandsGenerator" />
paket add TypeScriptRequestCommandsGenerator --version 0.9.45
#r "nuget: TypeScriptRequestCommandsGenerator, 0.9.45"
#:package TypeScriptRequestCommandsGenerator@0.9.45
#addin nuget:?package=TypeScriptRequestCommandsGenerator&version=0.9.45
#tool nuget:?package=TypeScriptRequestCommandsGenerator&version=0.9.45
CsharpToTypeScriptConverter - Solution Documentation
Table of Contents
- Project Overview
- Architecture
- Project Structure
- Core Components
- Key Models
- Type Name Resolution
- Type Generation Strategies
- Type Dependencies
- Generation Modes
- Usage Guide
- Development Guide
- Testing
Project Overview
CsharpToTypeScriptConverter is a .NET 9.0 code generation library that automatically converts C# types (classes, interfaces, enums) to equivalent TypeScript code. This tool enables seamless synchronization of type definitions between a C# backend API and a TypeScript frontend client.
Key Features
- Converts C# classes, interfaces, and enums to TypeScript with full type information
- Supports complex generic types including nested generics and arrays
- Handles class inheritance and interface implementation
- Generates either a single file or multiple organized separated files
- Preserves XML documentation from C# code as JSDoc comments
- Supports command patterns with
ICommand<T>andIRequestCommandinterfaces - Generates type metadata for JSON deserialization
- Intelligent type name resolution for generics and type parameters
Use Case
This library is designed for communication between an ASP.NET API and a TypeScript client using a command-based architecture. It ensures type safety and consistency across language boundaries while maintaining domain language clarity. The library automatically tracks type dependencies and generates proper imports for modular TypeScript code.
Architecture
High-Level Architecture
CsharpToTypeScriptConverter
└── TypeScriptGenerator (Entry Point)
├── OneFileGenerator (Single TypeScript file output)
│ ├── OneFileGeneratorWithMetaData
│ └── Templates/OneFile/TypesScriptGenerator
│
└── SeparatedFilesGenerator (Multiple TypeScript files)
├── SeparatedFilesGeneratorWithMetaData
├── SeparatedFilesGeneratorWithRenderedTypes
├── BuildedSeparatedFiles
└── Templates/SeparatedFiles/*
├── Commands/
├── ComplexTypes/
├── Enumerations/
├── Interfaces/
└── Imports/
TypeNameResolver (Type Analysis)
└── Handles generics, arrays, nullable types
MetadataHelper (Metadata Extraction)
└── Orchestrates GeneratorTypes strategies
GeneratorTypes (Type-Specific Generation)
├── ClassGeneratorType
├── EnumGeneratorType
└── InterfaceGeneratorType
TypeDependencyResolver (Dependency Analysis)
└── Tracks type dependencies with configurable options
Design Patterns Used
- Strategy Pattern: Separate generators for each type kind (Class, Enum, Interface)
- Static Factory Pattern:
ClassGeneratorType.Get(),EnumGeneratorType.Get()for type metadata creation - Builder Pattern: Generator classes build output step-by-step
- Template Method Pattern: T4 templates (
.ttfiles) define code generation templates - Facade Pattern:
MetadataHelperorchestrates type generation strategies - Reflection: Uses .NET Reflection to analyze C# types and extract metadata
- Visitor-like Pattern:
TypeDependencyResolvertraverses type hierarchies
Project Structure
Solution Layout
D:\GIT\CsharpToTypeScriptConverter\
├── src\
│ ├── CsharpToTypeScriptConverter.Generator\
│ │ ├── Generator.cs (Main entry point)
│ │ ├── Generators\
│ │ │ └── TypeScript\
│ │ │ ├── TypeScriptGenerator.cs
│ │ │ ├── OneFile\
│ │ │ │ ├── OneFileGenerator.cs
│ │ │ │ └── OneFileGeneratorWithMetaData.cs
│ │ │ └── SeparatedFiles\
│ │ │ ├── SeparatedFilesGenerator.cs
│ │ │ ├── SeparatedFilesGeneratorWithMetaData.cs
│ │ │ ├── SeparatedFilesGeneratorWithRenderedTypes.cs
│ │ │ └── BuildedSeparatedFiles.cs
│ │ ├── Models\
│ │ │ ├── GeneratorType.cs
│ │ │ ├── GeneratorMember.cs
│ │ │ ├── GeneratorTypeKind.cs
│ │ │ ├── BuildFile.cs
│ │ │ ├── BuildFileType.cs
│ │ │ ├── FileMetadata.cs
│ │ │ ├── FileMetadataType.cs
│ │ │ └── TypeScriptImportDependency.cs
│ │ ├── Templates\
│ │ │ ├── SeparatedFiles\
│ │ │ │ ├── Commands\
│ │ │ │ ├── ComplexTypes\
│ │ │ │ ├── CommandInterface\
│ │ │ │ ├── Enumerations\
│ │ │ │ ├── CodeGenerationWarning\
│ │ │ │ └── TypeScriptImports\
│ │ │ └── OneFIle\
│ │ ├── Tools\
│ │ │ ├── DocumentationTools.cs
│ │ │ ├── MetadataHelper.cs
│ │ │ ├── TypeDependencyResolver.cs
│ │ │ ├── TypeDependencyResolverOptions.cs
│ │ │ ├── TypeFileGenerator.cs
│ │ │ ├── TypeNameResolver.cs
│ │ │ └── GeneratorTypes\
│ │ │ ├── ClassGeneratorType.cs
│ │ │ ├── EnumGeneratorType.cs
│ │ │ └── InterfaceGeneratorType.cs
│ │ └── TypeScriptRequestCommandsGenerator.csproj
│ │
│ └── CsharpToTypeScriptConverter.Tests\
│ ├── ClassGeneratorTypeTests.cs
│ ├── InheritanceTests.cs
│ ├── TypeNameResolverTests.cs
│ ├── OneFileGeneratorTests.cs
│ ├── SeparatedFilesGeneratorTests.cs
│ ├── TestDefinitionsData.cs
│ └── CsharpToTypeScriptConverter.Tests.csproj
│
├── README.md
├── SOLUTION_DOCUMENTATION.md
├── LICENSE
└── (Other solution files)
Directory Structure Details
Generators/
- Contains all code generation logic organized by output strategy (OneFile vs SeparatedFiles)
Templates/
- T4 text templates (
.ttfiles) that define TypeScript code generation templates - Auto-generated
.csfiles from templates using TextTemplatingFilePreprocessor - Organized by generation strategy and type category
Models/
- Data transfer objects representing C# and TypeScript metadata
GeneratorType: Core metadata for any C# type (class, enum, interface)GeneratorTypeKind: Enum distinguishing type categoriesGeneratorMember: Represents properties/fields with type information
Tools/
- Utility classes for reflection, documentation parsing, and type resolution
TypeNameResolver: Converts C# types to TypeScript type names (handles generics, arrays, primitives)DocumentationTools: Extracts XML documentation from .NET assembliesMetadataHelper: Orchestrates type metadata extraction using GeneratorTypes strategiesTypeDependencyResolver: Analyzes type dependencies with configurable resolution optionsTypeFileGenerator: Creates individual TypeScript files- GeneratorTypes/ folder: Strategy implementations for extracting metadata from different type kinds
Tests/
- Unit tests validating type generation, inheritance, generics, and resolver functionality
Core Components
1. Generator (Entry Point)
File: Generator.cs
public class Generator
{
public TypeScriptGenerator TypeScript()
{
return new TypeScriptGenerator();
}
}
Purpose: Main entry point for the library. Provides fluent API access to TypeScript generation capabilities.
2. TypeScriptGenerator
File: Generators/TypeScript/TypeScriptGenerator.cs
Purpose: Facade class providing access to different generation strategies.
Methods:
OneFile(): ReturnsOneFileGeneratorfor single-file outputSeparatedFiles(): ReturnsSeparatedFilesGeneratorfor multi-file output
3. TypeNameResolver
File: Tools/TypeNameResolver.cs
Purpose: Resolves C# types to their TypeScript type name equivalents
Key Features:
- Converts primitive types:
int→number,string→string,bool→boolean - Handles nullables:
int?→number - Resolves generic types:
IEnumerable<User>→User[] - Supports nested generics:
Dictionary<string, List<User>>→Dictionary<string, User[]> - Generates generic type definitions:
MyClass<T>→MyClass<T> - Handles arrays:
User[]→User[]
Key Methods:
Resolve(Type, bool, string?): Main method that converts C# type to TypeScript nameIsIEnumerableOfT(Type): Detects if type isIEnumerable<T>
Type Mappings:
Number types (int, double, etc.) → "number"
String types (string, char, Guid, DateTime) → "string"
bool → "boolean"
object → "any"
Nullable<T> → T (unwrapped)
IEnumerable<T> → T[] (converted to array)
Generic types → Preserve generic structure
4. MetadataHelper
File: Tools/MetadataHelper.cs
Purpose: Orchestrates type metadata extraction for multiple types
Key Methods:
GetGeneratorTypesMetadata(types, returnTypeFilter): Extracts metadata for classes, enums, and interfacesGetMetadataForCommands(types, interfaceFilter, commandInterface, replacementName): Extracts command-specific metadata with interface customization
Workflow:
- Filters types (excludes abstract, filters by interfaces)
- Delegates to appropriate
GeneratorTypestrategy (Class, Enum, Interface) - Returns list of fully populated
GeneratorTypeobjects
5. GeneratorType Strategies
Location: Tools/GeneratorTypes/
ClassGeneratorType
File: Tools/GeneratorTypes/ClassGeneratorType.cs
Purpose: Extracts metadata from C# class types
Key Methods:
Get(Type, returnTypeFilter): Standard class metadataGetCommand(Type, interfaceFilter?, replacementInterfaceName?): Command class metadata
Metadata Extracted:
- Name (resolved via
TypeNameResolver) - Base type name (inheritance support)
- Interface implementations
- Properties (only declared on this type, not inherited)
- JSON deserialization type
- XML documentation
EnumGeneratorType
File: Tools/GeneratorTypes/EnumGeneratorType.cs
Purpose: Extracts metadata from C# enum types
Key Methods:
Get(Type): Enum metadata extraction
Metadata Extracted:
- Enum name
- Enum members with their values
- XML documentation
InterfaceGeneratorType
File: Tools/GeneratorTypes/InterfaceGeneratorType.cs
Purpose: Extracts metadata from C# interface types
Key Methods:
Get(Type, returnTypeFilter): Interface metadata extraction
Implementation: Reuses ClassGeneratorType logic but sets Kind = GeneratorTypeKind.Interface
6. TypeDependencyResolver
File: Tools/TypeDependencyResolver.cs
Purpose: Analyzes and resolves type dependencies for import generation
Key Features:
- Recursive dependency resolution
- Configurable resolution options
- Filters built-in .NET types automatically
- Supports custom type ignoring
Configuration (via TypeDependencyResolverOptions):
ResolveProperties(default: true): Resolve types from propertiesResolveInterfaces(default: true): Resolve implemented interfacesResolveInherits(default: true): Resolve base typesResolveFields(default: false): Resolve types from fieldsResolveMethods(default: false): Resolve types from method signatures
Key Methods:
GetDependencies(Type, bool): Returns direct dependenciesGetAllDependencies(params Type[]): Returns all transitive dependencies
Type Classification:
public enum TypeKind
{
Unknown,
Class,
Interface,
Enum,
ValueType
}
Ignored Types:
- Primitive types:
bool,int,long,string,char - Collection interfaces:
IList,IEnumerable,ICollection,IQueryable - Generic collection interfaces:
IList<>,IEnumerable<>, etc.
7. Documentation Tools
File: Tools/DocumentationTools.cs
Purpose: Parses XML documentation from .NET assemblies and extracts developer-written documentation
Key Methods:
LoadXmlDocumentation(Assembly): Loads XML docs from assembly's.xmlfileLoadXmlDocumentation(string): Parses raw XML documentation contentGetDocumentation(Type|PropertyInfo|ParameterInfo): Retrieves documentation for specific membersOnlyDocumentationText(string): Extracts clean text from XML doc markup
Key Members:
LoadedXmlDocumentation: Dictionary caching parsed XML docs by member keyLoadedAssemblies: HashSet tracking loaded assemblies (prevents reloading)
8. OneFileGenerator
File: Generators/TypeScript/OneFile/OneFileGenerator.cs
Purpose: Generates all TypeScript types into a single .ts file
Key Methods:
- Configures generator settings
- Manages type metadata collection
- Transforms C# types to TypeScript using templates
Related Classes:
OneFileGeneratorWithMetaData: Extended version with metadata support
9. SeparatedFilesGenerator
File: Generators/TypeScript/SeparatedFiles/SeparatedFilesGenerator.cs
Purpose: Generates each TypeScript type into separate .ts files
Key Features:
- Organizes output by type category (commands, enums, complex types, interfaces)
- Manages import dependencies between files
- Generates warning comments in generated files
- Creates barrel exports (index.ts files)
Related Classes:
SeparatedFilesGeneratorWithMetaData: Metadata versionSeparatedFilesGeneratorWithRenderedTypes: Handles pre-rendered typesBuildedSeparatedFiles: Container for built file structure
Key Models
GeneratorType
File: Models/GeneratorType.cs
Represents a C# type converted to TypeScript metadata.
public class GeneratorType
{
public string Name { get; set; } // TypeScript type name
public string TypeNameForJsonDeserialization { get; set; } // Type reference for JSON
public string ReturnTypeName { get; set; } // For commands: return type
public GeneratorTypeKind Kind { get; set; } // Class, Enum, Interface, CommandClass
public IEnumerable<GeneratorMember> Members { get; set; } // Properties/fields with types
public string[] ImplementsInterfaceTypeNames { get; set; } // Implemented interfaces
public string BaseTypeName { get; set; } // Base class name (inheritance)
public string[] Documentation { get; set; } // XML docs as text array
public string GeneratedCode { get; set; } // Generated TypeScript code
public Type Type { get; set; } // Original C# type
// Computed property
public string CommandReturnTypeName { get; } // Extracts return type from ICommand<T>
}
New Properties (Recent Additions):
BaseTypeName: Supports class inheritance in TypeScript outputCommandReturnTypeName: Regex-based extraction of generic type fromICommand<T>
GeneratorMember
File: Models/GeneratorMember.cs
Represents a member (property/field) of a type.
Properties:
Name: Member nameType: C# Type referenceGenericName: TypeScript-resolved type nameIsDeclaredAsGeneric: Whether member is a generic parameterDocumentation: XML documentation
GeneratorTypeKind
File: Models/GeneratorTypeKind.cs
Enum distinguishing different type categories:
public enum GeneratorTypeKind
{
Interface,
Enum,
Class,
CommandClass // Class implementing ICommand<T>
}
BuildFile
File: Models/BuildFile.cs
Represents a generated TypeScript file ready for output.
Properties:
FileName: Output filenameFileType: Category of file (Command, Enum, ComplexType, Interface, etc.)FileContent: Generated TypeScript codeFilePath: Full path where file should be written
TypeScriptImportDependency
File: Models/TypeScriptImportDependency.cs
Represents an import statement needed between TypeScript files.
Type Name Resolution
The TypeNameResolver is the heart of accurate type conversion. It handles complex scenarios:
Example Resolutions
// Primitives
typeof(int) → "number"
typeof(string) → "string"
typeof(bool) → "boolean"
// Generics
typeof(IEnumerable<User>) → "User[]"
typeof(Dictionary<string, int>) → "Dictionary<string, number>"
typeof(MyClass<T1, T2>) → "MyClass<T1, T2>"
// Nested Generics
typeof(List<List<User>>) → "List<User[]>[]"
typeof(Dictionary<string, List<User>>) → "Dictionary<string, User[]>"
// Arrays
typeof(int[]) → "number[]"
typeof(User[]) → "User[]"
typeof(List<User>[]) → "List<User>[]"
// Nullables
typeof(int?) → "number"
typeof(string?) → "string"
// Generic Type Definitions
typeof(MyClass<>) → "MyClass<T>"
typeof(MyClass<,>) → "MyClass<T1, T2>"
Type Generation Strategies
Class Generation
Input: A C# class with properties and base type
public class User : BasePerson
{
public int Id { get; set; }
public string Name { get; set; }
}
Metadata Extraction:
- Resolve class name via
TypeNameResolver - Extract base type using
TypeNameResolver - Collect interface implementations
- Extract declared properties only (not inherited)
- Resolve each property type via
TypeNameResolver - Load XML documentation via
DocumentationTools
Output:
export class User extends BasePerson {
public id?: number;
public name?: string;
}
Enum Generation
Input: A C# enum
public enum Status
{
Active = 0,
Inactive = 1
}
Metadata Extraction:
- Resolve enum name
- Extract enum members (exclude
value__synthetic field) - Load XML documentation
Output:
export enum Status {
Active = 0,
Inactive = 1,
}
Interface Generation
Input: A C# interface
public interface ICommand<T>
{
// members
}
Metadata Extraction:
- Uses
ClassGeneratorTypelogic - Sets
Kind = GeneratorTypeKind.Interface - Extracts interface members
Type Dependencies
The TypeDependencyResolver enables intelligent import generation:
Dependency Resolution Example
public class Order
{
public List<OrderItem> Items { get; set; } // Depends on OrderItem
public User Customer { get; set; } // Depends on User
public OrderStatus Status { get; set; } // Depends on OrderStatus (Enum)
}
Configuration:
var resolver = new TypeDependencyResolver(
ignoreTypes: new List<Type> { typeof(SomeFrameworkType) },
options: new TypeDependencyResolverOptions
{
ResolveProperties = true,
ResolveInterfaces = true,
ResolveInherits = true,
ResolveMethods = false
}
);
Result:
var deps = resolver.GetDependencies(typeof(Order));
// Returns: [(OrderItem, Class), (User, Class), (OrderStatus, Enum)]
Transitive Dependencies:
var allDeps = resolver.GetAllDependencies(typeof(Order));
// Recursively gets dependencies of Order, OrderItem, User, OrderStatus, etc.
Generation Modes
Mode 1: One File Generation
Use Case: When you want all TypeScript types in a single .ts file
Entry Point: TypeScriptGenerator.OneFile()
Workflow:
- Collect all C# types to convert
- Extract metadata for each type
- Apply OneFileGenerator template to all types at once
- Include all imports at the top of the file
- Write single output file
Output Structure:
// Generated with all types in one file
export interface ICommand<T> { _?: T }
export class Order { items?: OrderItem[] }
export class OrderItem { ... }
export enum OrderStatus { ... }
Advantages:
- Simple structure
- Minimal file management
- Good for smaller projects
- No import management needed
Mode 2: Separated Files Generation
Use Case: When you want organized, modular TypeScript files
Entry Point: TypeScriptGenerator.SeparatedFiles()
Workflow:
- Collect all C# types to convert
- Extract metadata for each type
- Categorize types by kind (commands, enums, complex types, interfaces)
- Calculate import dependencies using
TypeDependencyResolver - Generate individual files for each type category or type
- Generate import statements for each file
- Create barrel exports (index.ts) for each category
- Write individual files to organized directory structure
Output Structure:
output/
├── commands/
│ ├── index.ts
│ ├── createOrder.ts
│ └── updateOrder.ts
├── enums/
│ ├── index.ts
│ └── orderStatus.ts
├── models/
│ ├── index.ts
│ ├── order.ts
│ └── orderItem.ts
├── interfaces/
│ ├── index.ts
│ └── iCommand.ts
└── generationWarning.ts
Advantages:
- Clear organization by type
- Easier to maintain and navigate
- Better for large projects
- Barrel exports for cleaner imports
- Automatic import management
Usage Guide
Basic Setup
1. Install NuGet Package
Install-Package CSharpToTypeScriptConverter
2. Define C# Types
// Command interface (generic return type)
public interface ICommand<T>;
// Request command marker interface
public interface IRequestCommand;
// Example command
public class CreateOrderCommand : IRequestCommand, ICommand<Order>
{
public int CustomerId { get; set; }
public List<OrderItem> Items { get; set; }
}
// Example model with inheritance
public class Order
{
public int Id { get; set; }
public List<OrderItem> Items { get; set; }
}
// Example enum
public enum OrderStatus
{
Pending,
Confirmed,
Shipped
}
3. Generate TypeScript (One File)
using TypeScriptRequestCommandsGenerator;
using TypeScriptRequestCommandsGenerator.Tools;
// Get all exported types from assembly
var exportedTypes = typeof(OrderStatus).Assembly.ExportedTypes;
// Define interfaces to search for
var requestCommandType = typeof(IRequestCommand);
// Get metadata for types
var typesMetadata = MetadataHelper.GetGeneratorTypesMetadata(
exportedTypes,
requestCommandType
);
// Generate TypeScript
var generator = new Generator();
var oneFileGen = generator.TypeScript().OneFile();
var transformedText = oneFileGen.Generate(typesMetadata.ToArray());
// Write to file
File.WriteAllText("./models.ts", transformedText);
4. Generate TypeScript (Separated Files)
// ... (setup same as above until generation)
// Generate separated files
var generator = new Generator();
var separatedGen = generator.TypeScript().SeparatedFiles();
var builtFiles = separatedGen.Generate(typesMetadata.ToArray());
// Write files
foreach (var file in builtFiles.BuildFiles)
{
var fullPath = Path.Combine("./output", file.FilePath);
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
File.WriteAllText(fullPath, file.FileContent);
}
Generated TypeScript Output Example
Input C# Code:
/// <summary>Order information</summary>
public class Order
{
/// <summary>Order identifier</summary>
public int Id { get; set; }
/// <summary>Order items list</summary>
public List<OrderItem> Items { get; set; }
}
public class OrderItem
{
public int ProductId { get; set; }
public int Quantity { get; set; }
}
public enum OrderStatus { Pending = 0, Shipped = 1 }
Output TypeScript (from separated files):
models/order.ts:
import { OrderItem } from './orderItem';
/**
* Order information
*/
export class Order {
/**
* Order identifier
*/
public id?: number;
/**
* Order items list
*/
public items?: OrderItem[];
}
models/orderItem.ts:
export class OrderItem {
public productId?: number;
public quantity?: number;
}
enums/orderStatus.ts:
export enum OrderStatus {
Pending = 0,
Shipped = 1,
}
Development Guide
Adding Support for New Type Kinds
To support generating a new type category:
- Create strategy class (e.g.,
Tools/GeneratorTypes/RecordGeneratorType.cs) - Implement metadata extraction using reflection
- Update
MetadataHelperto use new strategy - Add
GeneratorTypeKindenum value if needed - Create template (e.g.,
Templates/SeparatedFiles/Records/RecordTypeScriptGenerator.tt) - Add tests validating metadata extraction and output
Adding a New Template
T4 templates control code generation. To add support for a new type of output:
- Create template file (e.g.,
Templates/SeparatedFiles/MyType/MyTypeGenerator.tt) - Update project file (
.csproj) to register the template:<None Update="Templates/SeparatedFiles/MyType/MyTypeGenerator.tt"> <LastGenOutput>MyTypeGenerator.cs</LastGenOutput> <Generator>TextTemplatingFilePreprocessor</Generator> </None> - Implement template logic in the
.ttfile - Create extension class (e.g.,
MyTypeGeneratorExt.cs) for helper methods - Integrate into generator by calling template from generator class
Extending TypeNameResolver
To add custom type mappings:
- Add custom type to the appropriate HashSet (
numberTypes,stringTypes, etc.) - Or modify the resolution logic for special cases
- Add test cases to
TypeNameResolverTests
Adding Custom Dependency Filtering
To ignore specific types during dependency resolution:
var resolver = new TypeDependencyResolver(
ignoreTypes: new List<Type>
{
typeof(SpecialFrameworkType),
typeof(AnotherTypeToIgnore)
}
);
Testing Generated Output
Use unit tests to validate generation:
Key Test Classes:
TypeNameResolverTests.cs: Tests type name resolution (generics, arrays, primitives)ClassGeneratorTypeTests.cs: Tests class metadata extractionInheritanceTests.cs: Tests inheritance and generic base class handlingOneFileGeneratorTests.cs: Tests single-file generationSeparatedFilesGeneratorTests.cs: Tests multi-file generation
Testing Pattern:
- Define test C# types (classes, enums, interfaces)
- Call appropriate
GeneratorTypestrategy - Assert metadata is correct
- Optionally generate TypeScript and verify output
Testing
Running Tests
dotnet test
Test Coverage
Type Resolution Tests (TypeNameResolverTests.cs):
- Simple type names
- Single and multiple generic parameters
- Nested generics
- Generic arrays
- Generic properties
Type Generation Tests (ClassGeneratorTypeTests.cs):
- Simple class generation
- Generic class generation
- Interface detection
- Command class detection
Inheritance Tests (InheritanceTests.cs):
- Base type name resolution
- Generic base class support
- Member inheritance
Integration Tests:
OneFileGeneratorTests.cs: Full single-file generationSeparatedFilesGeneratorTests.cs: Full multi-file generation
Building and Publishing
Build:
dotnet build
Run Tests:
dotnet test
Create NuGet Package:
- Project is configured with
<GeneratePackageOnBuild>True</GeneratePackageOnBuild> - Build creates
.nupkgfile automatically - Package metadata in
.csproj:- Version: 0.9.1
- Description: Generates classes, enums, interfaces from C# to TypeScript
- Repository: https://github.com/a-t-k/CsharpToTypeScriptConverter
Key Architectural Decisions
1. Reflection-Based Type Analysis
- Decision: Use .NET Reflection instead of parsing source code
- Rationale: Works with compiled assemblies, handles complex scenarios
- Trade-off: Requires compiled types, not source-only
2. Strategy Pattern for Type Generation
- Decision: Separate generators for Class, Enum, Interface types
- Rationale: Each type kind has unique metadata extraction needs
- Trade-off: More classes to maintain, but clearer separation of concerns
3. TypeNameResolver Utility
- Decision: Centralized type-to-TypeScript-name resolution
- Rationale: Complex logic for generics, arrays, and type parameters
- Trade-off: Need to keep mappings in sync with TypeScript support
4. T4 Templates for Code Generation
- Decision: Use T4 text templates instead of string builders
- Rationale: Separate concerns (template design vs logic), cleaner code
- Trade-off: Need template preprocessing in build
5. Two Generation Strategies
- Decision: Support both one-file and separated-file modes
- Rationale: Different projects have different needs
- Trade-off: More code to maintain
6. Configurable Dependency Resolution
- Decision: Options class to control which dependencies to resolve
- Rationale: Flexibility for different use cases (properties only vs methods too)
- Trade-off: More complex configuration
7. Generic Interface Support
- Decision: Special handling for
ICommand<T>andIRequestCommand - Rationale: Command pattern is primary use case
- Trade-off: Less flexible than generic interface support
Common Issues and Solutions
Issue: XML Documentation Not Found
Cause: XML documentation file (.xml) not found in assembly directory
Solution:
- Ensure C# project has
<GenerateDocumentationFile>true</GenerateDocumentationFile> - Copy
.xmlfile to same directory as assembly - Load documentation before generating types
Issue: Type Not Generated
Cause: Type doesn't implement required interface (IRequestCommand/ICommand<T>) Solution:
- Check type implements required interfaces
- Verify assembly is passed to generator
- Check type visibility (must be public)
Issue: Missing Imports in Generated TypeScript
Cause: Dependency not tracked by TypeDependencyResolver Solution:
- Ensure all used types are in generated metadata
- Check
TypeDependencyResolverOptionsmatches your needs - Verify import path calculation in templates
Issue: Generic Type Name Incorrect
Cause: TypeNameResolver not recognizing the pattern
Solution:
- Check if type is
IEnumerable<T>(converted toT[]) - Verify generic parameters are properly formed
- Add test case to
TypeNameResolverTests
Issue: Base Type Not Generated in TypeScript
Cause: Inheritance or base type tracking not working Solution:
- Ensure C# class explicitly declares base type (not
object) - Check
GeneratorType.BaseTypeNameis populated - Verify template includes
extendskeyword for non-null base types
Performance Considerations
- Reflection Impact: Type analysis uses reflection; minimize assembly loads
- Caching: XML documentation is cached in
LoadedXmlDocumentation - Dependency Resolution:
GetAllDependencies()is recursive; use options to limit scope - Memory: Large projects may benefit from separated files generation
- File I/O: Batch file writes for performance
Future Enhancements
Potential improvements for future versions:
- Support for record types (C# 9+)
- Support for init-only properties
- Custom attribute-based generation control
- TypeScript strict mode optimizations
- Angular/React specific output modes
- JSON schema integration
- Performance optimizations for large codebases
- Support for nullable reference types annotations
- Generic constraint support
- Method signature generation for interfaces
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- Microsoft.CodeAnalysis (>= 4.14.0)
- Microsoft.CodeAnalysis.Common (>= 4.14.0)
- Microsoft.CodeAnalysis.CSharp (>= 4.14.0)
- System.CodeDom (>= 9.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.8 | 129 | 1/15/2026 |
| 1.1.7 | 95 | 1/12/2026 |
| 1.1.6 | 93 | 1/8/2026 |
| 1.1.5 | 88 | 1/8/2026 |
| 1.1.4 | 86 | 1/8/2026 |
| 1.1.3 | 90 | 1/8/2026 |
| 1.1.2 | 89 | 1/8/2026 |
| 1.1.1 | 88 | 1/7/2026 |
| 1.1.0 | 85 | 1/7/2026 |
| 1.0.0 | 85 | 1/6/2026 |
| 0.9.49 | 87 | 1/5/2026 |
| 0.9.48 | 90 | 1/5/2026 |
| 0.9.47 | 86 | 1/5/2026 |
| 0.9.46 | 87 | 1/4/2026 |
| 0.9.45 | 87 | 1/4/2026 |
| 0.9.44 | 90 | 1/3/2026 |
| 0.9.43 | 89 | 1/2/2026 |
| 0.9.42 | 93 | 1/2/2026 |
| 0.9.41 | 88 | 1/2/2026 |
| 0.9.4 | 87 | 1/2/2026 |