276 lines
6.6 KiB
TypeScript
276 lines
6.6 KiB
TypeScript
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' // 错误:不在枚举值中
|
||
// });
|
||
|
||
|
||
// ============ 示例 5: Object 类型 - 带 required 字段 ============
|
||
const api5 = {
|
||
"domain_manager": {
|
||
"update": {
|
||
"path": "domain_manager",
|
||
"key": "update",
|
||
"metadata": {
|
||
"args": {
|
||
"data": {
|
||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||
"type": "object",
|
||
"properties": {
|
||
"id": { "type": "string" },
|
||
"domain": { "type": "string" },
|
||
"appId": { "type": "string" },
|
||
"status": {
|
||
"type": "string",
|
||
"enum": ["active", "inactive"] as const
|
||
},
|
||
"config": {
|
||
"type": "object",
|
||
"properties": {
|
||
"ssl": { "type": "boolean" },
|
||
"cdn": { "type": "boolean" }
|
||
}
|
||
}
|
||
},
|
||
"required": ["domain"] as const, // 只有 domain 是必需的
|
||
"additionalProperties": false
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"list": {
|
||
"path": "domain_manager",
|
||
"key": "list",
|
||
"metadata": {
|
||
"args": {
|
||
"data": {
|
||
"type": "object",
|
||
"properties": {
|
||
"page": { "type": "number" },
|
||
"pageSize": { "type": "number" },
|
||
"status": {
|
||
"type": "string",
|
||
"enum": ["active", "inactive"] as const
|
||
}
|
||
}
|
||
// 没有 required 字段,所以所有字段都是可选的
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} as const;
|
||
|
||
const queryApi5 = createQueryApi({ api: api5 });
|
||
|
||
// ✅ 示例 5.1: 只传必需字段 domain
|
||
queryApi5.domain_manager.update({
|
||
data: {
|
||
domain: "example.com" // domain 是必需的
|
||
}
|
||
});
|
||
|
||
// ✅ 示例 5.2: 传必需字段 + 可选字段
|
||
queryApi5.domain_manager.update({
|
||
data: {
|
||
domain: "example.com", // 必需
|
||
id: "123", // 可选
|
||
appId: "app-001", // 可选
|
||
status: "active", // 可选,且只能是 "active" | "inactive"
|
||
config: { // 可选对象
|
||
ssl: true,
|
||
cdn: false
|
||
}
|
||
}
|
||
});
|
||
|
||
// ❌ 错误:缺少必需字段 domain
|
||
// queryApi5.domain_manager.update({
|
||
// data: {
|
||
// id: "123" // 错误:缺少必需字段 "domain"
|
||
// }
|
||
// });
|
||
|
||
// ✅ 示例 5.3: list 方法所有字段都是可选的
|
||
queryApi5.domain_manager.list({
|
||
data: {
|
||
page: 1,
|
||
pageSize: 10
|
||
}
|
||
});
|
||
|
||
// ✅ 示例 5.4: list 方法可以传空对象
|
||
queryApi5.domain_manager.list({
|
||
data: {}
|
||
});
|
||
|
||
// ✅ 示例 5.5: list 方法甚至可以不传参数
|
||
queryApi5.domain_manager.list();
|
||
|
||
|
||
// ============ 类型检查 ============
|
||
type UpdateParams = Parameters<typeof queryApi5.domain_manager.update>[0];
|
||
// 推断为: { data: { domain: string } & { id?: string, appId?: string, status?: "active" | "inactive", config?: {...} } }
|
||
|
||
type ListParams = Parameters<typeof queryApi5.domain_manager.list>[0];
|
||
// 推断为: { query?: { page?: number, pageSize?: number, status?: "active" | "inactive" } }
|
||
|
||
|
||
console.log('✅ 所有类型推断示例运行成功!');
|