簡體   English   中英

Typescript 返回具有未知鍵的對象數組

[英]Typescript returning array of objects with unknown keys

我是 TypeScript 的新手,正在嘗試將現有的 JS (react) 項目慢慢遷移到 TypeScript。

我有一個 function 執行查詢:

/**
 * 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[],但 object 的內容取決於查詢。

關於如何最好地將此代碼移至 TS 的任何建議?

這是必須告訴類型系統您所期望的那些地方之一。 自然地,您在這樣做時必須非常小心,以確保您向類型系統提供准確的信息。 通常您希望盡早執行此操作,以便構建在其上的更復雜的代碼可以依賴於類型。

所以分兩部分回答:

  1. 如何鍵入query ,以及

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

首先,您可以通過給它一個泛型類型參數來告訴它返回什么類型的對象,使query成為一個泛型 function:

/**
 * 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 的用武之地:我不會這樣做,除非在 function 中你定義一次,它的工作是告訴你有多少行匹配:

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 注入攻擊的一部分,並繼續使用准備好的語句。)

游樂場鏈接

你必須使用 generics

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

但是 function 可以返回空數組。 在這種情況下,您可以像這樣檢查cnt屬性

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM