chore: bump version to 0.0.43, enhance JSON Schema type inference, and add usage examples
This commit is contained in:
164
test/json-schema-examples.ts
Normal file
164
test/json-schema-examples.ts
Normal file
@@ -0,0 +1,164 @@
|
||||
import { createQueryApi } from '../src/query-api.ts';
|
||||
|
||||
// ============ 示例 1: 基础 JSON Schema 推断 ============
|
||||
const api1 = {
|
||||
"user": {
|
||||
"get": {
|
||||
"path": "user",
|
||||
"key": "get",
|
||||
"metadata": {
|
||||
"args": {
|
||||
"userId": {
|
||||
"type": "string"
|
||||
},
|
||||
"includeProfile": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} as const;
|
||||
|
||||
const queryApi1 = createQueryApi({ api: api1 });
|
||||
|
||||
// ✅ 类型推断正常工作
|
||||
queryApi1.user.get({
|
||||
userId: '123', // ✅ 推断为 string
|
||||
includeProfile: true // ✅ 推断为 boolean
|
||||
});
|
||||
|
||||
// ❌ TypeScript 会报错
|
||||
// queryApi1.user.get({
|
||||
// userId: 123, // 错误:应该是 string
|
||||
// wrongProp: 'test' // 错误:不存在的属性
|
||||
// });
|
||||
|
||||
|
||||
// ============ 示例 2: 嵌套对象 JSON Schema(你的场景)============
|
||||
const api2 = {
|
||||
"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 queryApi2 = createQueryApi({ api: api2 });
|
||||
|
||||
// ✅ 类型推断正常工作 - data 参数被推断为 { id: string, domain: string }
|
||||
queryApi2.app_domain_manager.get({
|
||||
data: {
|
||||
id: '123',
|
||||
domain: 'example.com'
|
||||
}
|
||||
});
|
||||
|
||||
// ❌ TypeScript 会报错
|
||||
// queryApi2.app_domain_manager.get({
|
||||
// data: {
|
||||
// wrongProp: 'test' // 错误:不存在的属性
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
// ============ 示例 3: 复杂嵌套结构 ============
|
||||
const api3 = {
|
||||
"product": {
|
||||
"create": {
|
||||
"path": "product",
|
||||
"key": "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" },
|
||||
"size": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} as const;
|
||||
|
||||
const queryApi3 = createQueryApi({ api: api3 });
|
||||
|
||||
// ✅ 复杂嵌套类型推断
|
||||
queryApi3.product.create({
|
||||
product: {
|
||||
name: 'T-Shirt',
|
||||
price: 29.99,
|
||||
tags: ['clothing', 'summer'],
|
||||
metadata: {
|
||||
color: 'blue',
|
||||
size: 'M'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// ============ 示例 4: 枚举类型 ============
|
||||
const api4 = {
|
||||
"order": {
|
||||
"updateStatus": {
|
||||
"path": "order",
|
||||
"key": "updateStatus",
|
||||
"metadata": {
|
||||
"args": {
|
||||
"orderId": { "type": "string" },
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["pending", "processing", "shipped", "delivered"] as const
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} as const;
|
||||
|
||||
const queryApi4 = createQueryApi({ api: api4 });
|
||||
|
||||
// ✅ 枚举类型推断
|
||||
queryApi4.order.updateStatus({
|
||||
orderId: 'ORD-123',
|
||||
status: 'shipped' // ✅ 自动提示: "pending" | "processing" | "shipped" | "delivered"
|
||||
});
|
||||
|
||||
// ❌ TypeScript 会报错
|
||||
// queryApi4.order.updateStatus({
|
||||
// orderId: 'ORD-123',
|
||||
// status: 'invalid-status' // 错误:不在枚举值中
|
||||
// });
|
||||
|
||||
|
||||
console.log('✅ 所有类型推断示例运行成功!');
|
||||
@@ -10,34 +10,34 @@ console.log("JSON Schema for the person object:");
|
||||
console.log(
|
||||
JSON.stringify(toJSONSchema(schema), null, 2)
|
||||
);
|
||||
const jsonSchema = toJSONSchema(schema);
|
||||
// const jsonSchema = toJSONSchema(schema);
|
||||
|
||||
const schema2 = z.fromJSONSchema(jsonSchema);
|
||||
// const schema2 = z.fromJSONSchema(jsonSchema);
|
||||
|
||||
// schema2 的类型是 ZodSchema<any>,所以无法在编译时推断出具体类型
|
||||
// 这是 fromJSONSchema 的限制 - JSON Schema 转换会丢失 TypeScript 类型信息
|
||||
// // schema2 的类型是 ZodSchema<any>,所以无法在编译时推断出具体类型
|
||||
// // 这是 fromJSONSchema 的限制 - JSON Schema 转换会丢失 TypeScript 类型信息
|
||||
|
||||
schema2.parse({
|
||||
name: "John Doe",
|
||||
age: 30, // 添加必需的 age 字段
|
||||
email: "",
|
||||
})
|
||||
// schema2.parse({
|
||||
// name: "John Doe",
|
||||
// age: 30, // 添加必需的 age 字段
|
||||
// email: "",
|
||||
// })
|
||||
|
||||
type Schema2Type = z.infer<typeof schema2>;
|
||||
// Schema2Type 被推断为 any
|
||||
// type Schema2Type = z.infer<typeof schema2>;
|
||||
// // Schema2Type 被推断为 any
|
||||
|
||||
// 对比:原始 schema 的类型推断是正常的
|
||||
type OriginalSchemaType = z.infer<typeof schema>;
|
||||
// OriginalSchemaType = { name: string; age: number; email?: string | undefined }
|
||||
// // 对比:原始 schema 的类型推断是正常的
|
||||
// type OriginalSchemaType = z.infer<typeof schema>;
|
||||
// // OriginalSchemaType = { name: string; age: number; email?: string | undefined }
|
||||
|
||||
const v: Schema2Type = {
|
||||
name: "John Doe",
|
||||
email: ""
|
||||
}
|
||||
// const v: Schema2Type = {
|
||||
// name: "John Doe",
|
||||
// email: ""
|
||||
// }
|
||||
|
||||
// 如果使用原始 schema,类型推断会正常工作:
|
||||
const v2: OriginalSchemaType = {
|
||||
name: "John Doe",
|
||||
age: 30,
|
||||
// email 是可选的
|
||||
}
|
||||
// // 如果使用原始 schema,类型推断会正常工作:
|
||||
// const v2: OriginalSchemaType = {
|
||||
// name: "John Doe",
|
||||
// age: 30,
|
||||
// // email 是可选的
|
||||
// }
|
||||
Reference in New Issue
Block a user