共享类型包策略
创建供整个单体仓库使用的专用类型包
共享类型包策略 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。
为什么需要共享类型包
在前端和后端之间共享类型,可以消除 API 契约之间的偏差。单一事实来源意味着 API 结构发生变化时会出现编译时错误。
// packages/types/src/index.ts
export interface User { id: string; name: string; email: string; }
export interface ApiResponse<T> { data: T; error?: string; }包结构
请保持类型包精简:只导出类型,不包含运行时逻辑。这样可以使它没有副作用,并且支持树摇优化。
packages/types/
├── src/
│ ├── index.ts # re-exports all
│ ├── user.ts
│ ├── product.ts
│ └── api.ts
├── tsconfig.json
└── package.json类型包的 tsconfig 配置
请启用 emitDeclarationOnly,这样不会输出 JavaScript,只会生成供使用者引用的 .d.ts 文件。
{
"compilerOptions": {
"composite": true,
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "./dist",
"rootDir": "./src"
}
}使用类型包
请在 API 和 Web 应用中引用类型包,并使用 import type 导入类型,以避免运行时开销。
import type { User, ApiResponse } from "@myapp/types";
async function getUser(id: string): Promise<ApiResponse<User>> {
// ...
}保持类型可安全序列化
客户端和服务器之间共享的类型只能包含可通过 JSON 序列化的值。请避免使用 Date 对象,改用 string(ISO)。
// Good: serialization-safe
interface Event { id: string; createdAt: string; /* ISO date */ }
// Bad: Date is not JSON-serializable
interface Event { id: string; createdAt: Date; }管理类型包的版本
请使用语义化版本控制管理类型包的版本。破坏性变更(例如移除或重命名字段)需要提升主版本。
# Breaking change: major bump
npm version major
# Adding optional fields: minor bump
npm version minor从 OpenAPI 生成类型
请使用 openapi-typescript 根据 OpenAPI 规范生成类型包,从而实现自动化。这可以确保类型始终与后端一致。
npx openapi-typescript ./api/openapi.yaml -o ./packages/types/src/api.ts使用 Zod 实现运行时与编译时类型
请使用 Zod 模式定义类型,并从中推断 TypeScript 类型。运行时验证和静态类型都来自同一个来源。
import { z } from "zod";
export const UserSchema = z.object({ id: z.string(), name: z.string() });
export type User = z.infer<typeof UserSchema>;避免循环依赖
类型包不应从其他工作区包导入内容,以防止形成循环依赖链。请将它保持为依赖关系图中的叶节点。
// types/ should not import from ui/ or api/
// ui/ and api/ both import from types/测试类型正确性
请使用 tsd 编写类型级断言,验证共享类型是否符合预期。
import { expectType } from "tsd";
import type { User } from "@myapp/types";
expectType<User>({ id: "1", name: "Alice", email: "a@b.com" });回顾:共享类型策略
共享类型包可以消除 API 偏差:只输出声明文件,保持类型可通过 JSON 序列化,使用语义化版本控制,可选择从 OpenAPI 自动生成,并使用 tsd 进行测试。
快速检查
为什么共享 API 类型应使用 string 而不是 Date?
您学到的内容
共享类型包是 API 契约的单一事实来源。请让它只包含声明文件,确保类型可通过 JSON 安全序列化,使用语义化版本控制,并可选择从 OpenAPI 自动生成,以消除前端与后端之间的偏差。
常见问题解答
「共享类型包策略」课时是免费的吗?
是的 — 「共享类型包策略」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。
「共享类型包策略」这节课中我会学到什么?
创建供整个单体仓库使用的专用类型包 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 TypeScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「共享类型包策略」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 TypeScript Academy 课中编写并运行代码吗?
能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。