Appearance
使用 ApiTypingMeta 泛型支持
概述
API-Typing 现在支持泛型,允许用户自定义 API 类型定义,而不必依赖自动生成的类型文件。这为开发者提供了更大的灵活性,可以:
- 使用自定义 API 类型定义
- 覆盖或扩展默认的 ApiTypingMeta 接口
- 支持多个 API 模式定义
- 更容易地重新定义接口类型
基本用法
使用默认类型(向后兼容)
typescript
import { createHTTPClient } from 'api-typing'
// 使用默认的 ApiTypingMeta,与之前完全相同
const client = createHTTPClient({
baseURL: 'https://api.example.com'
})
// 所有现有代码继续正常工作
const response = await client.get('/pets/{id}', {
params: { id: 1 }
})
使用自定义 API 类型
typescript
import { createHTTPClient, type ApiTyping } from 'api-typing'
// 定义自定义 API 类型
interface CustomApiTypes extends ApiTyping {
paths: {
"/users/{id}": {
get: {
parameters: {
path: { id: number }
query?: { include?: string }
}
responses: {
200: {
content: {
"application/json": {
id: number
name: string
email: string
}
}
}
}
}
}
"/users": {
post: {
parameters: {}
requestBody: {
content: {
"application/json": {
name: string
email: string
}
}
}
responses: {
201: {
content: {
"application/json": {
id: number
name: string
email: string
}
}
}
}
}
}
}
components: {
schemas: {
User: {
id: number
name: string
email: string
}
}
}
operations: {}
external: {}
}
// 创建使用自定义类型的客户端
const customClient = createHTTPClient<CustomApiTypes>({
baseURL: 'https://api.example.com'
})
// 现在拥有完全的类型安全
const user = await customClient.get('/users/{id}', {
params: { id: 123 },
query: { include: 'profile' }
})
// user.data 的类型为: { id: number; name: string; email: string }
const newUser = await customClient.post('/users', {
name: 'John Doe',
email: 'john@example.com'
})
// newUser.data 的类型为: { id: number; name: string; email: string }
高级用法
扩展现有 API 类型
如果您有自动生成的类型文件,也可以扩展它们:
typescript
import { createHTTPClient } from 'api-typing'
import type { ApiTypingMeta } from 'api-typing'
// 扩展默认的 ApiTypingMeta
interface ExtendedApiTypes extends ApiTypingMeta {
paths: ApiTypingMeta['paths'] & {
"/custom/endpoint": {
get: {
parameters: {}
responses: {
200: {
content: {
"application/json": {
customData: string
}
}
}
}
}
}
}
}
const extendedClient = createHTTPClient<ExtendedApiTypes>()
组合多个 API 定义
typescript
interface ApiA extends ApiTyping {
paths: {
"/api-a/resource": {
get: {
parameters: {}
responses: {
200: {
content: { "application/json": { dataA: string } }
}
}
}
}
}
components: {}
operations: {}
external: {}
}
interface ApiB extends ApiTyping {
paths: {
"/api-b/resource": {
get: {
parameters: {}
responses: {
200: {
content: { "application/json": { dataB: number } }
}
}
}
}
}
components: {}
operations: {}
external: {}
}
// 组合多个 API
interface CombinedApi extends ApiTyping {
paths: ApiA['paths'] & ApiB['paths']
components: ApiA['components'] & ApiB['components']
operations: ApiA['operations'] & ApiB['operations']
external: ApiA['external'] & ApiB['external']
}
const combinedClient = createHTTPClient<CombinedApi>()
类型提取工具
所有现有的类型提取工具都支持泛型参数:
typescript
import type {
PathKeyOfMethod,
ExtractMethodResponseStatusContentJSON,
Extract200JSON,
GetArgs,
PostArgs
} from 'api-typing'
// 使用自定义类型提取路径
type GetPaths = PathKeyOfMethod<'get', CustomApiTypes>
// 结果: "/users/{id}"
// 提取响应类型
type UserResponse = ExtractMethodResponseStatusContentJSON<
'get',
200,
'/users/{id}',
CustomApiTypes
>
// 结果: { id: number; name: string; email: string }
// 提取请求参数类型
type GetUserArgs = GetArgs<'/users/{id}', CustomApiTypes>
// 结果: ["/users/{id}", { params: { id: number }; query?: { include?: string } }]
迁移指南
从现有代码迁移
如果您已经在使用 API-Typing,无需任何更改。所有现有代码将继续工作,因为泛型类型有默认值。
逐步采用自定义类型
- 开始时:继续使用默认类型
- 逐步添加:为新的 API 端点定义自定义类型
- 完全自定义:定义完整的自定义 API 类型
typescript
// 阶段 1: 默认类型
const client = createHTTPClient()
// 阶段 2: 混合使用
interface PartialCustom extends ApiTypingMeta {
paths: ApiTypingMeta['paths'] & {
// 添加新的自定义端点
"/new-endpoint": { /* ... */ }
}
}
// 阶段 3: 完全自定义
interface FullyCustom extends ApiTyping {
// 完全自定义的类型定义
}
最佳实践
- 类型文件组织:将自定义类型定义放在单独的文件中
- 渐进式采用:从小的自定义开始,逐步扩展
- 类型复用:使用 TypeScript 的类型操作符来复用和组合类型
- 文档化:为自定义类型添加注释和文档
typescript
// types/api.ts
export interface MyApiTypes extends ApiTyping {
paths: {
// 详细的类型定义和注释
}
components: {
schemas: {
// 可复用的模型定义
}
}
operations: {}
external: {}
}
// client.ts
import type { MyApiTypes } from './types/api'
import { createHTTPClient } from 'api-typing'
export const apiClient = createHTTPClient<MyApiTypes>({
baseURL: process.env.API_BASE_URL
})
通过这种方式,API-Typing 提供了强大的类型系统,既保持了向后兼容性,又为复杂的使用场景提供了灵活性。