A TypeSpec emitter that generates C# model classes, interfaces, enums, ASP.NET Core controllers, and service interfaces from TypeSpec definitions.
For each TypeSpec model the emitter produces:
- A
public partial class <Name>that implements its companion interface. - A
public partial interface I<Name>with the same property signatures (optional — disable withemit-interfaces: false).
TypeSpec enum declarations become C# enums with [JsonConverter(typeof(EnumMemberConverterFactory))] and optional [EnumMember(Value = "...")] attributes. When HTTP operations are present the emitter also generates controllers and service interfaces. Each output type can be disabled independently via the emit-* options.
npm install --save-dev @massivescale/tsp-aspnetcore-apiAdd the emitter to tspconfig.yaml and run the compiler:
emit:
- "@massivescale/tsp-aspnetcore-api"
options:
"@massivescale/tsp-aspnetcore-api":
root-namespace: MyCompany.Apinpx tsp compile .With root-namespace: MyCompany.Api and the TypeSpec below, the emitter writes Users/User.g.cs and Users/IUser.g.cs:
@doc("A registered user")
namespace MyCompany.Api.Users;
model User {
@format("uuid") id: string;
name: string;
active: boolean;
joined?: utcDateTime;
}// Users/User.g.cs
// <auto-generated/>
#nullable enable
using System;
using System.Collections.Generic;
namespace MyCompany.Api.Users
{
/// <summary>
/// A registered user
/// </summary>
public partial class User : IUser
{
public Guid? Id { get; set; }
public string? Name { get; set; }
public bool? Active { get; set; }
public DateTimeOffset? Joined { get; set; }
}
}| Option | Type | Default | Description |
|---|---|---|---|
abstract-suffix |
string |
"Base" |
Suffix appended to generated abstract controller class names, e.g. UsersControllerBase. |
additional-usings |
string[] |
[] |
Extra using directives added to every generated file. |
cancellation-token |
boolean |
true |
When true, adds CancellationToken cancellationToken to every controller action and service method, and emits using System.Threading; in controller and service files. |
controllers-output-dir |
string |
"Controllers" |
Destination for generated controller files. |
controllers-root-namespace |
string |
(global root) | Overrides root-namespace for controller files. The full namespace is <controllers-root-namespace>.<controllers-output-dir>. |
emit-controllers |
boolean |
true |
When false, no controller base class files are emitted. |
emit-helpers |
boolean |
false |
When false, helper files are skipped unless required by generated output. MergePatchValue is emitted automatically when any MergePatchUpdate<T> model is generated; enum converter helpers still follow this option. |
emit-interfaces |
boolean |
true |
When false, no I<Model> interface files are emitted. |
emit-services |
boolean |
true |
When false, no service interface files are emitted. |
emit-validators |
boolean |
false |
When true, FluentValidation validator classes are generated for models that appear as POST or PATCH request bodies. See FluentValidation validators. |
file-extension |
string |
".g.cs" |
File extension for all generated files. |
helpers-output-dir |
string |
"Helpers" |
Destination for generated helper files (EnumMemberConverterFactory, MergePatchValue). |
interfaces-output-dir |
string |
"Models" |
Destination for generated interface files. |
interfaces-root-namespace |
string |
(global root) | Overrides root-namespace for interface files only. |
models-output-dir |
string |
"Models" |
Destination for generated class and enum files. Relative paths resolve against emitter-output-dir. |
models-root-namespace |
string |
(global root) | Overrides root-namespace for model and enum files only. Affects the fallback namespace for unnamespaced types and folder-path stripping when namespace-from-path is false. |
namespace-from-path |
boolean |
true |
When true, output-dir path segments are appended to the TypeSpec namespace for models/interfaces/enums, and are used as the namespace for controllers/services/helpers. See Namespace resolution. |
namespace-map |
Record<string, string> |
{} |
Rewrites TypeSpec namespaces to C# namespaces. Longest-prefix match wins; sub-namespaces inherit the rewrite automatically. |
nullable-properties |
boolean |
true |
When true, all properties are emitted as nullable (string?, int?). When false, only TypeSpec-optional properties and T | null unions are nullable. |
root-namespace |
string |
(inferred) | Root C# namespace. Stripped from folder paths so the directory tree mirrors the namespace hierarchy beneath it. When omitted, inferred from the TypeSpec namespace tree. |
route-prefix |
string |
"api" |
Prefix prepended to every controller route, e.g. "api" → /api/v1/users. |
services-output-dir |
string |
"Services" |
Destination for generated service interface files. |
services-root-namespace |
string |
(global root) | Overrides root-namespace for service interface files. The full namespace is <services-root-namespace>.<services-output-dir>. |
templates |
Record<string, string> |
{} |
Custom Handlebars template paths keyed by template name. See Custom templates. |
validators |
"post" | "patch" | "both" |
"both" |
Controls which validator type(s) are emitted per model. "post" emits {Model}Validator.g.cs; "patch" emits {Model}PatchValidator.g.cs; "both" emits both. |
validators-output-dir |
string |
"Validators" |
Output directory for generated validator and initializer files. |
validators-root-namespace |
string |
(global root) | Overrides root-namespace for validator files. The full namespace is <validators-root-namespace>.<validators-output-dir>. |
validators-version-strategy |
"earliest" | "latest" | "per-version" | "version-aware" |
(auto) | Controls how versioning affects validator generation. Auto-detected: "version-aware" when @versioned is present, "earliest" otherwise. See Version strategies. |
- Type Mapping — TypeSpec-to-C# scalar and collection mappings,
@formatoverrides - Model Generation — Default property values, enums, cross-namespace references
- Namespace Resolution — How C# namespaces are derived from output paths and TypeSpec namespaces
- Controllers and Services — ASP.NET Core controller and service interface generation
- RFC 7396 Merge Patch —
MergePatchUpdate<T>support andMergePatchValue<T>wrapper - FluentValidation Validators — Validator generation, constraint mapping, version strategies
- Custom Templates — Handlebars template overrides and view model reference
- Development — Build, test, and project structure