You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript:为泛型SQL函数封装默认泛型类型的实现问询

问题解答

1. 当前实现是否正确?

你的实现完全正确。

insertQuery通过Parameters<typeof executeQuery>完整继承了executeQuery的参数类型,同时将泛型Result的默认值设为OkPacket,既复用了核心查询逻辑,又实现了不同操作场景下的默认类型区分。从你提供的类型验证示例来看,VSCode能正确推导packet为OkPacket、numberPacket为number,说明类型约束完全生效,符合预期。

2. 是否有更简便的实现方案?

当前封装方案已经轻量简洁,不过可以根据需求考虑以下替代方案:

方案一:函数重载

无需单独封装insertQuery,直接给executeQuery添加重载签名,区分查询和插入场景的默认返回类型:

// 查询操作默认返回 RowDataPacket[]
async function executeQuery(
  event: CompatibilityEvent,
  query: string,
  values?: any[],
  onError?: ErrorEmitter
): Promise<[RowDataPacket[], FieldPacket[]]>;

// 插入操作可指定泛型,默认返回 OkPacket
async function executeQuery<Result = OkPacket>(
  event: CompatibilityEvent,
  query: string,
  values?: any[],
  onError?: ErrorEmitter
): Promise<[Result, FieldPacket[]]>;

// 核心实现
async function executeQuery<Result = RowDataPacket[]>(
  event: CompatibilityEvent,
  query: string,
  values: any[] = [],
  onError: ErrorEmitter
): Promise<[Result, FieldPacket[]]> {
  // 原有逻辑
}

这种方式省去了额外的包装函数,但需要调用者明确场景(或通过泛型指定),可读性不如单独封装insertQuery直观。

方案二:语义化类型别名

通过类型别名强化不同操作的返回类型语义,保持现有包装函数不变:

type QueryResult<T = RowDataPacket[]> = [T, FieldPacket[]];
type InsertResult<T = OkPacket> = QueryResult<T>;

// 修改 executeQuery 返回类型
export async function executeQuery<Result = RowDataPacket[]>(
  event: CompatibilityEvent,
  query: string,
  values: any[] = [],
  onError: ErrorEmitter
): Promise<QueryResult<Result>> {
  // 原有逻辑
}

export function insertQuery<Result = OkPacket>(...params: Parameters<typeof executeQuery>) {
  return executeQuery<Result>(...params) as Promise<InsertResult<Result>>;
}

这种方式仅优化了类型的可读性,核心逻辑和原有方案一致。

3. TypeScript是否内置此类功能?

TypeScript本身没有针对SQL操作场景的内置封装或专属类型,你当前使用的泛型默认值、Parameters工具类型等都是TypeScript的通用类型特性,已经被合理利用。针对SQL操作的类型区分,需要开发者根据业务场景自行封装。


内容的提问来源于stack exchange,提问作者Casper Kuethe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:57:09