如何在 TypeScript 中输入 node-postgres 异步查询函数?

How to type node-postgres async query functions in TypeScript?

我对 TypeScript 还很陌生,并开始将我现有的服务器从 ES6 转换为 TypeScript。我有点迷茫,想弄清楚如何为异步函数声明类型。这是 ES6 代码的存根:

// db.js
import { Pool } from 'pg';

const pool = new Pool({
  connectionString: 'process.env.DB_CONNECTION',
});

export default {

  query(text, params) {
    return new Promise((resolve, reject) => {
      try {
        const result = pool.query(text, params);
        return resolve(result);
      } catch (error) {
        return reject(error);
      }
    });
  },
};

// controller for a table
const Table = {
  getOne: async (id) => {
    return await db.query('SELECT * FROM table WHERE id=', [id]);
  },
}

这很好用,可以通过消费 try/catch 块中的部分来处理,无论查询 return 是结果还是错误,它都有效。现在我应该如何在打字稿中输入这些内容?我试过这样做:

import { Pool } from 'pg';

const pool = new Pool({
  connectionString: 'process.env.DB_CONNECTION',
});

export default {

  query(text: string, params: any[]) {
    return new Promise((resolve, reject) => {
      try {
        const result = pool.query(text, params);
        return resolve(result);
      } catch (error) {
        return reject(error);
      }
    });
  },
};

// controller
import { QueryResult } from 'pg';

const Table = {
  getOne: async (id: string) => {
    return await db.query('SELECT * FROM table WHERE id=', [id]) as QueryResult;
  },
}

现在,可以编译了,但是有几件事我没有明白。首先,总是将这些 return 类型转换为 'as' 是非常多余的。难道我不能像这样 getOne: async (id: string): Promise<QueryResult> => {...} 那样声明 return 类型吗?那么,如果诺言被拒绝,会发生什么?这不再是 QueryResult 类型了。我试图阅读有关 node-postgres 和 TypeScript 函数类型声明的文档,但我一无所获。我应该怎么做这些?也可能我也应该开始学习声明文件了。

异步函数隐含return 承诺

示例:

// Declare async function
async function getRandomNumberAsync(max: number): Promise<number> {
  return Math.floor(Math.random() * Math.floor(max));
}

// Call it (errors are handled with a try/catch)
try {
  const result = await getRandomNumberAsync(100);
  console.log(result);
} catch (e) {
  console.error("something went wrong");
}

async/await 只是语法糖(在幕后,async/await 使用 Promises)。这段代码和上面的代码基本等价

function getRandomNumberAsync(max: number): Promise<number> {
  return Promise.resolve(Math.floor(Math.random() * Math.floor(max)));
}

getRandomNumberAsync(100).then(result => {
  console.log(result);
}).catch(e => {
  console.error("something went wrong");
})

我可以看到,在您的代码中,您使用的 return await 是多余的。甚至还有一个 eslint rule 来防止这个

您的代码应如下所示

const Table = {
  getOne: async (id: string): Promise<QueryResult> => {
    return db.query('SELECT * FROM table WHERE id=', [id]);
  },
}

// "getOne" should be called like this
try {
  const result = await Table.getOne("YOUR_ID");
  // handle result
} catch (e) {
  // handle error
}

除非您想处理 query 内部的错误 getOne

它应该看起来像这样

const Table = {
  getOne: async (id: string): Promise<QueryResult | string> => {
    try {
      return await db.query("SELECT * FROM table WHERE id=", [id]);
    } catch (e) {
      return "something went wrong";
    }
  },
}