0Pricing
TypeScript Academy · 课时

共享类型包策略

创建供整个单体仓库使用的专用类型包

共享类型包策略 是 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. TypeScript 项目引用详解
  2. 使用 TypeScript 配置 pnpm 工作区
  3. 共享类型包策略
  4. 单体仓库中的增量构建与缓存
← 返回 TypeScript Academy