Dekiru.TypeScriptClientBuilder
6.2.2
Prefix Reserved
See the version list below for details.
dotnet add package Dekiru.TypeScriptClientBuilder --version 6.2.2
NuGet\Install-Package Dekiru.TypeScriptClientBuilder -Version 6.2.2
<PackageReference Include="Dekiru.TypeScriptClientBuilder" Version="6.2.2" />
<PackageVersion Include="Dekiru.TypeScriptClientBuilder" Version="6.2.2" />
<PackageReference Include="Dekiru.TypeScriptClientBuilder" />
paket add Dekiru.TypeScriptClientBuilder --version 6.2.2
#r "nuget: Dekiru.TypeScriptClientBuilder, 6.2.2"
#:package Dekiru.TypeScriptClientBuilder@6.2.2
#addin nuget:?package=Dekiru.TypeScriptClientBuilder&version=6.2.2
#tool nuget:?package=Dekiru.TypeScriptClientBuilder&version=6.2.2
TypeScript Client Builder
A .NET library that automatically generates TypeScript client code and DTOs from ASP.NET Core controllers. Reduce boilerplate and keep your frontend and backend in sync.
Features
- Automatic Client Generation: Generates TypeScript HTTP client methods from your ASP.NET Core controllers
- DTO Export: Automatically exports C# DTOs to TypeScript interfaces
- Enum Support: Multiple enum export options (numbers, strings, unions, const enums)
- Type Safety: Full type safety between your C# API and TypeScript client
- Inheritance Support: Optional support for inheritance chains in generated types
- Record Type Support: C# records are automatically converted to TypeScript interfaces
- NDJSON Streaming: Server-sent streaming with automatic callback generation
- Customizable: Extensive configuration options for indentation, naming, and behavior
- Checksum Optimization: Skip regeneration when nothing has changed
- XML Documentation: Import your XML documentation comments into TypeScript
- Flexible Parameters: Support for named parameters, headers, event callbacks, and more
Installation
Install via NuGet:
dotnet add package Dekiru.TypeScriptClientBuilder
Or via Package Manager Console:
Install-Package Dekiru.TypeScriptClientBuilder
Quick Start
Basic Usage
Add the following to your ASP.NET Core application (typically in Program.cs):
using TypeScriptClientBuilder;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
// Generate TypeScript client
ClientBuilder.Build(new ClientConfiguration
{
Output = "ClientOutput"
});
app.Run();
This will scan all your controllers and generate TypeScript files in the ClientOutput directory.
Example Controller
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get(CancellationToken cancellationToken)
{
// Your implementation
}
}
This generates a TypeScript client with type-safe methods to call your API.
Helpful for LLMs
Library Architecture & Namespaces
The TypeScriptClientBuilder library uses the following main namespaces:
TypeScriptClientBuilder- Root namespace for the libraryTypeScriptClientBuilder.Attributes- Custom attributes for controlling generation (ClientBuilderAttribute, UnionTypeAttribute, etc.)TypeScriptClientBuilder.Primitives- Core data models representing parsed controller structure (Controller, Method, Parameter, TsType)TypeScriptClientBuilder.Utils- Utility classes for code generation (TypeNameResolver, TypeScriptWriter, TypeExporter)TypeScriptClientBuilder.Streaming- Streaming result types (NdJsonResult)
Entry Points & Configuration
Main Entry Point:
TypeScriptClientBuilder.ClientBuilder.Build(ClientConfiguration configuration)
Configuration Object:
The ClientConfiguration class contains all library settings for customization:
- Output directory, file cleaning, checksum validation
- Type generation preferences (inheritance, partials, nullability)
- Method signature options (named parameters, generic methods, event callbacks)
- Enum export strategies (strings, union types, const enums)
- Advanced options (XML documentation, includes, custom type formatters)
Core Components Deep Dive
1. Controller Parsing (ExportService.CreateModel())
- Scans assemblies for
[ApiController]decorated classes - Extracts HTTP verb information (HttpGet, HttpPost, etc.)
- Parses route templates from controller and method attributes
- Collects method parameters and metadata
2. Type Export Pipeline (TypeExporter.Export)
- Recursively processes all types used in returned values and parameters
- Handles type relationships: DTOs, enums, generic types, arrays, dictionaries
- Tracks exported types to prevent duplication
- Applies nullable type transformations
3. Type Resolution Engine (TypeNameResolver.Resolve)
This component converts C# types to TypeScript types with intelligent handling:
System.String → string
int? → { [key]?: T };
MyNamespace.UserDto → { name: string; id: number; };
List<Item> → Item[];
Dictionary<string, User> → { [key: string]: User };
Task<T> → Promise<T>;
IEnumerable<T> → T[];
NdJsonResult<T> → T (with streaming callbacks)
4. TypeScript Code Generation (TypeScriptWriter)
Handles code generation for different export types:
BeginInterface()- Defines TypeScript interfaces with appropriate propertiesBeginEnum()- Creates enum definitions based on EnumTypes configurationWriteStartTSDoc()- Generates JSDoc comments from XML documentation- Block nesting with automatic indentation management
Type System Documentation
Primitives Namespace Classes:
Controller- Represents a parsed controller with methods collectionMethod- Represents a controller action with HTTP verb, route, and type infoParameter- Represents a method parameter with binding type and TypeScript typeTsType- Core CLR type representation with type system operations (IsArray, IsEnum, IsDto, GenericTypeArguments)Description- XML documentation wrapper for methods and properties
Utils Namespace Classes:
TypeNameResolver- Complex type mapping from C# to TypeScript with context-aware transformationsTypeExporter- Type management, export tracking, and registrationTypeScriptWriter- Low-level TypeScript code generation with block managementTypeNameResolver- Type name resolution and transformation for proper output
Streaming Namespace:
NdJsonResult- Server-sent streaming result type for large data handling
Attribute System:
ClientBuilderAttribute(with ClientBuilderSettings flags) - Controls generation behavior at controller/method levelClientBuilderMethodNameAttribute- Customizes generated method namesClientBuilderReturnsUrlAttribute/ClientBuilderRedirectAttribute- Controls file download behaviorAddQueryParameterAttribute- Adds implicit query parametersUnionTypeAttribute- Generates string union types like"value1" | "value2" | "value3"TypedIdOfAttribute- Overrides property types for custom type transformationsPartialAttribute- Creates Partial<T> types for partial dataKeyOfAttribute- Generates keyof T typesNullableAttribute/OptionalAttribute- Explicit property nullability/optional markers
Generation Workflow
- Controller Discovery - Assemblies scanned for controllers with [ApiController] attribute
- Method Extraction - HTTP verb attributes (HttpGet, HttpPost, etc.) trigger method discovery
- Type Analysis - TypeScript type resolution for return types and parameters
- Export Registration - Controllers and DTOs registered for code generation
- Type Normalization - Enums, nullable types, and generic types processed
- Code Writing - TypeScript interfaces, enums, and client methods written to Output directory
- File Structure
Generated output directory contains:
Output/
├── HttpClient.ts # Base client implementation
├── Enums.ts # All enum definitions
├── Dto.ts # All DTO interfaces
└── <ControllerName>.ts # Controller-specific methods
Programmatic Usage Patterns
Custom Type Formatting:
TypeFormatter = type => type.Name + "Dto"
Wildcard Includes:
Includes = new HashSet<string>
{
"MyApi.Types.*", // Include all types in namespace
"MyApi.Controllers.*" // Include all controller exports
}
Custom Logging:
LoggingCallback = message => Logger.Info($"[ClientBuilder] {message}")
Complete API Reference Summary
Key Enums:
ExportType- (Controller, DTO, Enum) Export categoryFileResultBehavior- (Redirect, Uri) File download return strategyEnumTypes(Flags) - (None, Strings, Union, Const) Enum export optionsClientBuilderSettings(Flags) - (AddHeader, AddEventCallback, AddReturnXhrFlag, OmitHeader, OmitEventCallback, OmitReturnXhrFlag)
Core Classes:
ClientBuilder.Build(ClientConfiguration config)- Initializes and runs generationTypeExporter.GetDTOs()- Returns collected DTO typesTypeExporter.GetEnums()- Returns collected enum types
Common TypeScript Types Generated:
- Interfaces for C# classes and records
- Type-safe method signatures with parameter objects
- Enum translations based on EnumTypes configuration
- nullability handling with ? suffix or optional<T>
This architecture enables the library to provide end-to-end TypeScript client generation while maintaining flexibility for advanced use cases and customizations.
Configuration Options
ClientConfiguration
| Property | Type | Default | Description |
|---|---|---|---|
Output |
string |
Required | Output directory for generated files |
CleanOutput |
bool |
false |
Delete existing .ts files before generation |
UseChecksum |
bool |
false |
Skip generation if checksum matches |
UseVerboseLogging |
bool |
false |
Enable detailed logging |
XmlDocumentationFile |
string |
null |
Path to XML documentation file |
UseInheritance |
bool |
false |
Generate separate types for inheritance chains |
EnumType |
EnumTypes |
None |
How to export enums (Strings, Union, Const) |
ConvertNullablePropsToOptional |
bool |
false |
Convert nullable properties to optional |
UseNamedParameters |
bool |
false |
Use object parameters instead of parameter lists |
GenericMethods |
bool |
false |
Generate methods with generic return types |
DisableTypeChecking |
bool |
true |
Add // @ts-nocheck to generated files |
TypeFormatter |
Func<ExportedType, string> |
Identity | Custom type name formatter |
AddHeaderParameter |
bool |
false |
Include header parameter in methods |
AddEventCallback |
bool |
false |
Include XHR event callback parameter |
AddReturnXhrFlag |
bool |
false |
Include flag to return XHR object on error |
LoggingCallback |
Action<string> |
null |
Custom logging callback |
Indentation |
Indentation |
4 spaces | Indentation settings |
IFormFileType |
string |
"Blob" |
TypeScript type for IFormFile |
DefaultFileResultBehavior |
FileResultBehavior |
Redirect |
Behavior for file result methods |
Includes |
HashSet<string> |
Empty | Force include types (supports wildcards, e.g. MyNamespace.*) |
Example Configuration
ClientBuilder.Build(new ClientConfiguration
{
Output = "wwwroot/api",
CleanOutput = true,
UseChecksum = true,
XmlDocumentationFile = "bin/Debug/net8.0/MyApi.xml",
EnumType = EnumTypes.Strings | EnumTypes.Union,
ConvertNullablePropsToOptional = true,
UseNamedParameters = true,
Indentation = new Indentation
{
Character = ' ',
Size = 2
},
LoggingCallback = message => Console.WriteLine($"[ClientBuilder] {message}")
});
Attributes
Controller & Method Attributes
[ClientBuilderAttribute]
Configure client generation at controller or method level using ClientBuilderSettings flags:
| Flag | Description |
|---|---|
AddHeader |
Add header parameter to generated methods |
AddEventCallback |
Add XHR event callback parameter |
AddReturnXhrFlag |
Add flag to return XHR object on error |
OmitHeader |
Omit header parameter (overrides controller-level setting) |
OmitEventCallback |
Omit event callback (overrides controller-level setting) |
OmitReturnXhrFlag |
Omit return XHR flag (overrides controller-level setting) |
[ClientBuilder(ClientBuilderSettings.AddHeader | ClientBuilderSettings.AddEventCallback)]
public class MyController : ControllerBase
{
[ClientBuilder(ClientBuilderSettings.OmitHeader)]
public IActionResult MyMethod() { }
}
[ClientBuilderIgnore]
Exclude controllers, methods, properties, or parameters from generation:
[ClientBuilderIgnore]
public class InternalController : ControllerBase { }
[ClientBuilderMethodName]
Override the generated method name:
[ClientBuilderMethodName("fetchWeather")]
public IActionResult GetWeather() { }
[ClientBuilderReturnsUrl] / [ClientBuilderRedirect]
Control file download behavior (GET requests only):
[ClientBuilderReturnsUrl]
public FileResult DownloadFile() { }
[AddQueryParameter]
Add query parameters without declaring them in the method:
[AddQueryParameter("version", typeof(int))]
public IActionResult Get() { }
Type Attributes
[UnionType]
Generate string union types:
public class Model
{
[UnionType("success", "error", "pending")]
public string Status { get; set; }
}
Generates: status: "success" | "error" | "pending"
[KeyOf]
Generate keyof types:
public class Model
{
[KeyOf(typeof(User))]
public string Field { get; set; }
}
Generates: field: keyof User
[TypedIdOf]
Override property type:
public class Model
{
[TypedIdOf(typeof(User))]
public int UserId { get; set; }
}
[Partial]
Generate Partial<T> types. You can optionally specify a type override:
public IActionResult Update([Partial] User user) { }
// With explicit type
public IActionResult Patch([Partial(typeof(UserDto))] User user) { }
[Nullable] / [Optional]
Mark properties as nullable or optional:
public class Model
{
[Nullable]
public string Name { get; set; }
[Optional]
public int? Age { get; set; }
}
NDJSON Streaming
Return NdJsonResult<T> from a controller action to stream data as newline-delimited JSON. The generator automatically produces a TypeScript method with an onData callback instead of a regular return value.
[HttpGet("stream")]
public NdJsonResult<WeatherForecast> GetStream(int count)
{
return new NdJsonResult<WeatherForecast>(GetForecasts(count));
}
private async static IAsyncEnumerable<WeatherForecast> GetForecasts(int count)
{
for (var i = 0; i < count; i++)
{
await Task.Delay(500);
yield return new WeatherForecast { /* ... */ };
}
}
Alternatively, you can use the factory method:
return NdJsonResult.Create(GetForecasts(count));
The generated TypeScript method will look like:
getStream(count: number, onData: (data: StreamedResponse<WeatherForecast>) => void): Promise<void>
StreamedResponse<T> includes properties for the streamed data and completion status. The final chunk will have done: true to indicate the end of the stream.
Supported Frameworks
- .NET 8.0
- .NET 9.0
- .NET 10.0
Development
Building
dotnet build
Running Sample
The Sample project demonstrates the library's features:
cd Sample
dotnet run
Check the Output directory for generated TypeScript files.
Publishing to NuGet (Internal use only)
Update version in
Source/TypeScriptClientBuilder.csproj:<BaseVersion>6.2.0</BaseVersion> <PreviewVersion>-preview.1</PreviewVersion>Preview versions will have
-preview.xsuffix, while stable releases will leave thePreviewVersionempty.Commit and push changes
Run the DevOps pipeline
Package will appear on nuget.org within a few minutes
License
MIT
Authors
Dekiru Solutions
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. 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 is compatible. 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. |
-
net10.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
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 |
|---|---|---|
| 6.2.4 | 106 | 5/13/2026 |
| 6.2.3 | 81 | 5/13/2026 |
| 6.2.2 | 85 | 5/13/2026 |
| 6.2.1 | 85 | 5/13/2026 |
| 6.2.0 | 136 | 3/11/2026 |
| 6.2.0-preview.1 | 62 | 2/13/2026 |
| 6.2.0-preview.0 | 66 | 2/13/2026 |
| 6.1.3 | 401 | 10/20/2025 |
| 6.1.2 | 204 | 10/15/2025 |
| 6.1.1 | 201 | 10/15/2025 |
| 6.1.0 | 283 | 9/19/2025 |
| 6.1.0-preview.1 | 182 | 8/13/2025 |
| 6.1.0-preview.0 | 156 | 6/3/2025 |
| 6.0.4 | 692 | 3/4/2025 |
| 6.0.3 | 207 | 3/3/2025 |
| 6.0.2 | 197 | 2/20/2025 |
| 6.0.1 | 184 | 1/30/2025 |
| 6.0.0-preview | 168 | 10/11/2024 |
| 5.0.16 | 4,436 | 8/29/2024 |
| 5.0.15 | 822 | 5/30/2024 |