Typescript返回键值未知的对象数组



我是TypeScript新手,正在尝试将现有的JS (react)项目慢慢迁移到TypeScript中。

我有一个执行查询的函数:

/**
* Run a Query against the currently connected database
* @param {String} sql Query to run
* @param {Object[]} Array of objects to be used in the prepared statement
* @returns {Promise<Object[]>} Promise resolving after query is done. Returns an array of arrays with the result.
*/
const query = (sql, params) => {
//Database stuff
}

我在很多地方调用这个:

const result = await query('SELECT count(*) as cnt from Table id=?',[2]')
return result[0].cnt

最后一行出现错误,因为字段"cnt"是未知的。如何最好地解决这个问题?返回类型始终是Object[],但对象的内容取决于查询。

有什么建议如何最好地移动这个代码到TS?

这是必须告诉类型系统所期望的内容的地方之一。当然,您在这样做时必须非常小心,以确保您向类型系统提供了准确的信息。通常,您希望尽可能早地这样做,以便构建在其上的更复杂的代码可以依赖于这些类型。

所以答案分为两部分:

  1. 如何输入query,和

  2. 避免直接使用query的建议

首先,你可以让query成为一个泛型函数,给它一个泛型类型参数,告诉它返回什么类型的对象:

/**
* Run a Query against the currently connected database
* @param {string} sql Query to run
* @param {any[]} Array of objects to be used in the prepared statement
* @returns {Promise<ResultType[]>} Promise resolving after query is done. Returns an array of arrays with the result.
*/
const query = <ResultType extends object>(sql: string, params: any[]): Promise<ResultType[]> => {
// −−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^
//Database stuff
};

然后你可以这样使用:

const result = await query<{cnt: number}>('SELECT count(*) as cnt from Table id=?', [2]);
// −−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^
return result[0].cnt;
但这就是第2条的用武之地:我不会这样做,除非在函数中只定义一次它的工作是告诉您匹配的行数:
async function getCountFromExampleTable(id: number): Promise<number> {
const result = await query<{cnt: number}>('SELECT count(*) as cnt from Table id=?', [id]);
return result[0].cnt;
}

很容易看到getCountFromExampleTable并知道我们给出的类型参数({cnt: number})是正确的。然后,任何需要这样做的代码都可以重用getCountFromExampleTable,而不必提供该类型参数(可能会出错)。

您可能希望getCountFromExampleTable更通用,可能接受表名和参数,但是您明白了。(如果是这样,请务必测试表名,以确保它不会被用作SQL注入攻击的一部分,并继续使用已准备好的语句。)

操场上联系

必须使用泛型

const query = <T>(sql: string, params: Object[]): T[] => {
return []
}

但是函数可以返回空数组。在本例中,您可以像这样检查cnt属性

const result = await query('SELECT count(*) as cnt from Table id=?',[2])
return result[0]?.cnt

最新更新