TypeScript编译错误:Query类型无法分配给[any[], any]类型
问题:TypeScript编译错误及类型不兼容问题
报错信息
- 编译错误:
TSError: ⨯ Unable to compile TypeScript: return new TSError(diagnosticText, diagnosticCodes, diagnostics); - 类型错误:
Type 'Query' is not assignable to type '[any[], any]',对应代码行:const [results]: [any[], any] = await conn.query(sql, [imageId, sevenDaysAgo]);
问题代码
router.get("/votes/statistics/:imageId", async (req, res) => { const imageId = parseInt(req.params.imageId); // Extract imageId from URL // Calculate the date 7 days ago from the current date const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); // SQL query to retrieve vote statistics const sql = ` SELECT DATE(votedate) AS voteDate, COUNT(*) AS voteCount FROM Votes WHERE imageId = ? AND votedate >= ? GROUP BY DATE(votedate) ORDER BY voteDate`; try { // Retrieve data from the database const [results]: [any[], any] = await conn.query(sql, [imageId, sevenDaysAgo]); // Ensure that results is an array before iterating over it if (!Array.isArray(results)) { throw new Error("Query results are not iterable"); } // Iterate over the results and construct the vote statistics array const voteStatistics = results.map(row => ({ voteDate: row.voteDate, voteCount: row.voteCount, })); res.json({ success: true, imageId, voteStatistics }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: "An error occurred while fetching data" }); } });
解决方案
1. 修正返回值类型断言
TypeScript无法自动识别conn.query的返回值为可解构的数组类型,需要通过类型断言明确其结构,替换原来的类型注解:
// 用类型断言告知TS返回值结构 const [results] = await conn.query(sql, [imageId, sevenDaysAgo]) as [any[], any];
如果使用mysql2库,推荐导入官方类型以获得更精确的类型提示:
import { RowDataPacket } from 'mysql2'; // 指定查询结果的类型 const [results] = await conn.query<RowDataPacket[]>(sql, [imageId, sevenDaysAgo]);
2. 移除冗余数组检查
当通过类型断言或泛型指定results为数组类型后,TypeScript已能确认其类型,可移除冗余的Array.isArray检查代码。
3. 定义明确的业务类型(可选)
为了提升类型安全性,可定义查询结果的接口:
interface VoteStat { voteDate: string; voteCount: number; } // 查询时直接指定类型 const [results] = await conn.query<VoteStat[]>(sql, [imageId, sevenDaysAgo]);
这样后续map操作时,TypeScript会自动推断row的类型,避免使用any。
修改后的完整代码
import { RowDataPacket } from 'mysql2'; import express from 'express'; const router = express.Router(); // 可选:定义业务类型 interface VoteStat { voteDate: string; voteCount: number; } router.get("/votes/statistics/:imageId", async (req, res) => { const imageId = parseInt(req.params.imageId); const sevenDaysAgo = new Date(); sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); const sql = ` SELECT DATE(votedate) AS voteDate, COUNT(*) AS voteCount FROM Votes WHERE imageId = ? AND votedate >= ? GROUP BY DATE(votedate) ORDER BY voteDate`; try { // 使用泛型指定查询结果类型 const [results] = await conn.query<VoteStat[]>(sql, [imageId, sevenDaysAgo]); const voteStatistics = results.map(row => ({ voteDate: row.voteDate, voteCount: row.voteCount, })); res.json({ success: true, imageId, voteStatistics }); } catch (error) { console.error(error); res.status(500).json({ success: false, message: "An error occurred while fetching data" }); } });
内容的提问来源于stack exchange,提问作者ทยากร สุธรรม
相关产品推荐
相关产品推荐

