【问题标题】:Strongly typing results from mysql2 in Typescript在 Typescript 中强类型化来自 mysql2 的结果
【发布时间】:2023-02-10 04:24:10
【问题描述】:

我正在使用 NextJS 和 Typescript 开发一个应用程序,并试图确定正确键入 MySQL 响应的最佳方式。这是 API 端点:

import { hash } from "bcrypt";
import type { NextApiRequest, NextApiResponse } from "next";
import randomstring from "randomstring";

import { executeQuery } from "../../../lib/db";

const Test = async (req: NextApiRequest, res: NextApiResponse) => {
  // Manage password generation
  const password = randomstring.generate(16);
  const hashedPassword = hash(password, 10);

  // Create new auth using email and password
  const auth = await executeQuery(
    "INSERT INTO auth (email, password) VALUES (?, ?)",
    ["test@test.com", (await hashedPassword).toString()]
  );

  res.statusCode = 200;
  res.json(auth.insertId);
};

export default Test;

我想通过 ESLint 强类型 insertId 来删除所有警告和错误,但不幸的是,我所做的一切努力都没有成功。我得到的错误是:

Property 'insertId' does not exist on type 'RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[] | ResultSetHeader | { error: unknown; }'.
  Property 'insertId' does not exist on type 'RowDataPacket[]'.ts(2339)

我的executeQuery 函数定义为:

import mysql from "mysql2/promise";

export const executeQuery = async (query: string, params: unknown[] = []) => {
  try {
    const db = await mysql.createConnection({
      host: process.env.MYSQL_HOST,
      database: process.env.MYSQL_DATABASE,
      user: process.env.MYSQL_USER,
      password: process.env.MYSQL_PASSWORD,
    });

    const [results] = await db.execute(query, params);
    db.end();

    return results;
  } catch (error) {
    return { error };
  }
};

我的实施尝试之一是this SO response,但我无法让它工作......

非常感谢任何帮助!

【问题讨论】:

    标签: mysql node.js typescript next.js


    【解决方案1】:

    因此,我在解决了一段时间后设法解决了自己的问题。

    事实证明,我做错了检查。

    在致电 auth.insertId 之前,您需要包括以下检查:

    if (!auth || !("insertId" in auth)) {
      // Do something
    }
    

    这样,您实际上不必键入任何内容,因为当您尝试使用 mysql 执行此操作时,它会变得非常复杂。

    【讨论】:

      【解决方案2】:

      在查找 mysql2 类型文件后,我发现自己也遇到了与您相同的问题,我发现您可以传递查询的结果类型。

      例如:

      connection.query<OkPacket>('INSERT INTO posts SET ?', {title: 'test'},
      function (error, results, fields) {
        if (error) throw error;
        console.log(results.insertId);
      });
      

      对于插入和更新,您可以使用OkPacket 类型,对于选择,您可以使用RowDataPacket。您可以通过将 RowDataPacket 实现为查询的预期响应类型并将其传递到查询函数中来进一步键入它。

      例如:

      export interface Post {
        title: string;
      }
      
      export interface PostRow extends RowDataPacket, Post {}
      

      然后当你查询时你可以通过如下方式:

      connection.query<PostRow[]>('SELECT * FROM users WHERE id = 1',
      function (error, results, fields) {
        if (error) throw error;
        // ...
      });
      

      这是我的 2 美分,希望它能帮助将来的人。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-28
        • 2017-05-12
        • 2016-01-02
        • 2020-07-10
        • 2019-04-26
        • 2018-01-07
        • 2020-12-27
        • 2021-11-25
        相关资源
        最近更新 更多