我有与此类似的代码 - 非常简单,只是为了展示案例。

this.getCode = (code: string): Promise<codeObject | false> => {
        return new Promise((resolve, reject) => {
            pool.query('SELECT * FROM ?? WHERE code = ?', [TABLE, code], function (err, result) {
                if (err) {
                    return reject(err);
                }

                if (result.length === 0) {
                    return resolve(false);
                }
            });
        });
    };

问题出在 if (result.length === 0) { ,错误是 error TS2339: Property 'length' does not exist on type 'RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[]'.
我找不到任何方法来重新定义 OkPacket 至少有 length?: number这足以忽略该错误(大多数选择无论如何都不会得到 OkPackets 并且我不想在每个选择上检查类型,如果我知道它不是 OkPacket 时我得到的不是 OkPacket)...

最佳答案

我也找不到合适的方法来处理这个问题,所以最后针对我的类似情况采用了这种解决方法:

const [rows,] = await connection.execute("SELECT id FROM users WHERE email = ?", [profile.email]);
if ((rows as any).length === 1) {
   return (rows as any)[0].id;
}
logger.error("Unexpected query response", rows);
throw Error("This code should never be executed");
您也可以使用 user defined type-guards 。像这样:
const isRowDataPacket = (rows: RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[] | ResultSetHeader): rows is RowDataPacket[] | RowDataPacket[][] => {
    return (rows as RowDataPacket[] | RowDataPacket[][]).length !== undefined
}
但是您仍然需要进一步进行类型转换以正确解释每一行:
const [rows,] = await connection.execute("SELECT id FROM users WHERE email = ?", [profile.email]);
if (isRowDataPacket(rows) && rows.length === 1) {
    return (rows[0] as { id: string }).id;
}

10-08 02:11