4.3 KiB
4.3 KiB
JSON Schema 类型推断优化说明
问题描述
之前在使用 createQueryApi 时,如果 API 定义使用 JSON Schema(而不是 Zod schema),参数类型会被推断为 unknown,导致失去类型安全性。
优化方案
修改内容
在 src/query-api.ts 中增强了 InferFromJSONSchema 和 InferType 类型,使其能够正确处理:
- 嵌套对象的 JSON Schema
- 带有
$schema字段的 JSON Schema - 没有
type字段但有properties字段的对象
核心改进
// 增强的 InferFromJSONSchema 类型
type InferFromJSONSchema<T> =
// ... 基础类型处理 ...
// 新增:处理没有 type 但有 properties 的对象
T extends Record<string, any>
? T extends { properties: infer P }
? { [K in keyof P]: InferFromJSONSchema<P[K]> }
: unknown
: unknown;
// 增强的 InferType 类型
type InferType<T> =
T extends z.ZodType<infer U> ? U :
T extends { type: infer TType } ? InferFromJSONSchema<T> :
T extends { properties: infer P } ? InferFromJSONSchema<T> : // 新增
T;
使用示例
示例 1: 基础 JSON Schema
const api = {
"user": {
"get": {
"path": "user",
"key": "get",
"metadata": {
"args": {
"userId": { "type": "string" },
"includeProfile": { "type": "boolean" }
}
}
}
}
} as const;
const queryApi = createQueryApi({ api });
// ✅ 完整的类型推断
queryApi.user.get({
userId: '123', // string
includeProfile: true // boolean
});
示例 2: 嵌套对象(你的场景)
const api = {
"app_domain_manager": {
"get": {
"path": "app_domain_manager",
"key": "get",
"metadata": {
"args": {
"data": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": { "type": "string" },
"domain": { "type": "string" }
}
}
}
}
}
}
} as const;
const queryApi = createQueryApi({ api });
// ✅ data 参数被正确推断为 { id: string, domain: string }
queryApi.app_domain_manager.get({
data: {
id: '123',
domain: 'example.com'
}
});
示例 3: 枚举类型
const api = {
"order": {
"updateStatus": {
"metadata": {
"args": {
"status": {
"type": "string",
"enum": ["pending", "processing", "shipped"] as const
}
}
}
}
}
} as const;
const queryApi = createQueryApi({ api });
// ✅ status 被推断为 "pending" | "processing" | "shipped"
queryApi.order.updateStatus({
status: 'shipped' // 自动补全和类型检查
});
示例 4: 复杂嵌套
const api = {
"product": {
"create": {
"metadata": {
"args": {
"product": {
"type": "object",
"properties": {
"name": { "type": "string" },
"price": { "type": "number" },
"tags": {
"type": "array",
"items": { "type": "string" }
},
"metadata": {
"type": "object",
"properties": {
"color": { "type": "string" }
}
}
}
}
}
}
}
}
} as const;
const queryApi = createQueryApi({ api });
// ✅ 深度嵌套的类型推断
queryApi.product.create({
product: {
name: 'T-Shirt', // string
price: 29.99, // number
tags: ['summer'], // string[]
metadata: {
color: 'blue' // string
}
}
});
支持的 JSON Schema 特性
- ✅ 基础类型:
string,number,integer,boolean - ✅ 对象类型:
type: "object"withproperties - ✅ 数组类型:
type: "array"withitems - ✅ 枚举类型:
enum字段 - ✅ 嵌套对象和数组
- ✅ 忽略
$schema等元数据字段 - ✅ 支持
as const断言以获得更精确的类型
类型安全
优化后,TypeScript 会:
- ✅ 提供完整的自动补全
- ✅ 在编译时检测类型错误
- ✅ 防止传入不存在的属性
- ✅ 确保值的类型正确
测试
运行测试文件验证类型推断:
bun test/json-schema-examples.ts