TypeScript正确输入查询结果MySQL

0ejtzxu1  于 2023-02-13  发布在  TypeScript
关注(0)|答案(2)|浏览(134)

我正在使用mysql2/promisenpm package连接并查询MySQL数据库,我在尝试为查询结果设置正确的类型时感到困惑,因为我事先不知道结果将是什么类型。
我创建了一个具有异步query方法的数据库类。

// Database.ts
import mysql, { Pool } from "mysql2/promise"; // import mysql2/promise

export class Database implements IDatabase {
  logger: ILogger;
  pool: Pool;

  constructor(logger: ILogger) {
      this.logger = logger;
      // pool connection is set up here
  }

  async query(sql: string, options?: unknown): Promise<unknown> { // type?
      const [rows] = await this.pool.query(sql, options);
      return rows;
  }
}

在我的服务器代码中,我希望能够执行类似以下的操作:

// server.ts
import { Database } from "./core/Database";
const db = new Database(logger);

app.get("/", async (req, res) => {
  const sql = `
      select *
      from users;
  `;
  const users: IUser[] = await db.query(sql); // get people

  // do some logic x

  // send response
  res.json({
      result: x
  });
});

使用unknown不起作用,因为我不能将它赋给我的类型,使用any可以,但是感觉不对。有没有一种干净的方法来做到这一点?

i5desfxk

i5desfxk1#

将函数键入为:

async query<T = unknown>(sql: string, options?: unknown): Promise<T[]> {

然后按如下方式使用函数:

const users = await db.query<IUser>(sql);
hmae6n7t

hmae6n7t2#

在@Evert和this answer的帮助下,我找到了一个解决方案
我创建了以下类型:

export type DbDefaults = RowDataPacket[] | RowDataPacket[][] | OkPacket[] | OkPacket;
export type DbQueryResult<T> = T & DbDefaults;

重写我的方法如下:

async query<T>(sql: string, options?: unknown): Promise<DbQueryResult<T[]>> {
  const [result] = await this.pool.query<DbQueryResult<T[]>>(sql, options);
  return result;
}

我现在可以这样使用它:

const sql = `
  select *
  from users;
`;

const people = await db.query<IUser>(sql);

也可以只转换为T

public async query<T>(sql: QueryString, parameters?: unknown[]): Promise<T[]> {
  const [rows] = await this.pool.query(sql, parameters);
  return rows as T[];
}

相关问题