我有与此类似的代码 - 非常简单,只是为了说明情况。
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);
}
});
});
};
问题在行中,如果 (result.length === 0( {,错误error TS2339: Property 'length' does not exist on type 'RowDataPacket[] | RowDataPacket[][] | OkPacket | OkPacket[]'.
我找不到任何方法来重新定义 OkPacket 至少具有length?: number
这足以忽略该错误(大多数选择无论如何都不会获得 OkPacket,如果我得到的不是 OkPacket,我不想在每个选择上检查类型,当我知道它不是(......
我遇到了类似的问题,并且能够通过检查查询中生成的行是否是数组来修复 TypeScript 给出的警告,"属性'长度'在类型'OkPacket'上不存在"。这对我来说比使用 JSON.stringify(( 将行转换为字符串要容易得多。
使用上面的原始示例,我将 result.length 比较更改为:
if (Array.isArray(result) && result.length === 0) {
return resolve(false);
}
我也找不到合适的方法来解决这个问题,所以最终为我的类似情况提供了这个解决方法:
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");
还可以使用用户定义的类型保护。喜欢这个:
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;
}
讨厌这个错误。这是我的解决方法:
const [rows] = await db.query(`mySqlHere`);
let tempResult: any = rows;
console.log(tempResult.length); // OK
<</div>
div class="one_answers"> 我也不喜欢这方面的设计选择,但我通常使用:
const [rows, fields] = await conn.execute(QUERY_STRING) as any
console.log(rows.length)
对于我自己的用例,map
没有在 OkPacket
中定义,因为我需要以下内容
function (error, results, fields) {
const data = results.map((item: any) => {
//... do stuffs..
return {
name: item.name,
username: item.username,
image: item.image,
bio: item.bio,
url: item.url,
}
})
resolve([results, fields]);
}
为了摆脱错误,我最终检查了结果对象中是否存在map
,如果不存在,则提前返回(仅 reject(( 不会修复错误(。修改代码如下
function (error, results, fields) {
if(!('map' in results)) {
reject(results);
return;
}
const data = results.map((item: any) => {
// ...do stuff...
return {
name: item.name,
username: item.username,
image: item.image,
bio: item.bio,
url: item.url,
}
})
resolve([results, fields]);
}
例如,对于您的情况,您可以检查length
,如果不存在,则提前返回。
if(!('length' in results)) {
reject(results);
return;
}