TypeSpec 是微软推出的基于 TypeScript 的接口定义语言,用于描述 RESTful API 结构,本身非 C# 一部分;通过 @typespec/csharp 插件可生成 C# 客户端代码,但不支持服务端自动生成,也不参与运行时编译。

TypeSpec 是什么,和 C# 有什么关系?
TypeSpec 本身不是 C# 的一部分,它是微软推出的、基于 TypeScript 的接口定义语言(IDL),用来描述 API(尤其是 RESTful 服务)的结构。它不直接生成 C# 类型,但可通过插件(如 @typespec/openapi3 + @typespec/csharp)输出 C# 客户端或服务端代码。关键点是:TypeSpec 不编译进运行时,它只在设计/生成阶段起作用。
如果你期望“写个 .tsp 文件就自动编译成可运行的 C# 项目”,那会失望——它更像 Swagger + TypeScript 的增强版,目标是统一契约、驱动多语言代码生成。
如何用 TypeSpec 定义一个简单 API 并生成 C# 客户端?
先确保安装了 Node.js 和 TypeSpec CLI:
npm install -g @typespec/cli
创建 main.tsp,定义一个待生成的 API:
import "@typespec/http"; import "@typespec/openapi3"; import "@typespec/csharp";@service({title: "TodoService"}) namespace TodoApi { @route("/todos") @get op listTodos(): Todo[];
@route("/todos/{id}") @get op getTodo(@path id: string): Todo; }
model Todo { @key id: string; name: string; completed: boolean; }
然后执行生成命令(需先安装 @typespec/csharp 插件):
npx tsp compile . --emit @typespec/csharp --option "@typespec/csharp.emitter-output-dir=./GeneratedClient"
生成的 C# 代码默认包含 TodoApiClient、Todo 模型等,使用的是 System.Net.Http 和 System.Text.Json,不依赖第三方 HTTP 客户端库。
本文档主要讲述的是maven使用方法;Maven是基于项目对象模型的(pom),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具。Maven将你的注意力从昨夜基层转移到项目管理层。Maven项目已经能够知道 如何构建和捆绑代码,运行测试,生成文档并宿主项目网页。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
-
@typespec/csharp目前仍为预览版,生成的代码可能缺少部分特性(如分页支持、自定义序列化器钩子) - 必须显式导入
@typespec/csharp,否则--emit会静默失败 - 路径参数(
@path)、查询参数(@query)、请求体(@body)需正确标注,否则生成的 C# 方法签名可能漏参数或类型错误
C# 服务端生成是否可行?
目前(2024 年中)@typespec/csharp 官方仅支持客户端生成(即调用方代码),不生成 ASP.NET Core Controller 或 Minimal API。想用 TypeSpec 驱动服务端,有两条现实路径:
- 用
@typespec/openapi3导出 OpenAPI JSON,再用NSwag或Microsoft.dotnet-openapi工具反向生成服务端骨架(但会丢失 TypeSpec 特有语义,如@visibility、@friendlyName) - 手动实现 Controller,并用
[ProducesResponseType]等特性对齐 OpenAPI 输出,再通过tsp compile . --emit @typespec/openapi3验证一致性 - 社区有实验性插件(如
typespec-csharp-server)尝试生成 Minimal API,但稳定性差、无官方维护,不建议用于生产
换句话说:TypeSpec 当前对 C# 服务端是“契约先行但手写实现”,而非“契约即实现”。
常见报错与绕过方式
运行 tsp compile 时容易遇到以下问题:
-
Error: Cannot resolve emitter "@typespec/csharp"→ 检查是否在项目根目录执行,且package.json中已声明@typespec/csharp为 devDependency;不要用全局npx tsp调用本地插件 - 生成的 C# 类名含非法字符(如
My-Resource)→ TypeSpec 默认转为 PascalCase,但连字符会被忽略导致冲突(MyResource和MyResource),改用@friendlyName("MyResource")显式指定 - DateTime 字段生成为
DateTimeOffset?而非DateTime?→ 这是 OpenAPI 3.0 对时间字段的规范行为,若后端强制用DateTime,需在 C# 客户端手动映射或改用@type注解配合自定义序列化器
最易被忽略的一点:TypeSpec 的 @doc、@summary 等注释默认不会出现在生成的 C# XML 注释里,需额外配置 --option "@typespec/csharp.include-docs=true" 才启用。









