有没有一种方法可以用TypeScript中的对象文字来组织我的数据库连接



我想在代码中编写两个不同的连接:一个用于生产,另一个用于开发。我还想用.env文件在这些连接之间进行选择。我尝试了几种方法,找到了这个解决方案:

// Modules
import dotenv from "dotenv";
import knex from "knex";
// Environment variables
dotenv.config();
const { PG_HOST, PG_PORT, PG_USER, PG_PASSWORD, PG_DB, IS_APP_IN_PRODUCTION } = process.env;
// Connections
const connectionsList = [
knex({
client: "pg",
connection: {
host: PG_HOST,
port: (PG_PORT as any),
user: PG_USER,
password: PG_PASSWORD,
database: PG_DB
}
}),
knex({
client: "sqlite3",
connection: {
filename: "./development/dev.sqlite3",
database: "dev-db"
}
})
];
// Setting the connection
const connection = connectionsList[IS_APP_IN_PRODUCTION == "true" ? 0 : 1];
// Export
export default connection;

这有效并解决了我的问题,但在我看来,这不是最好的解决方案。我不喜欢使用数组来组织我的连接;正因为如此,我的第一次尝试是使用对象文字来组织,方法是:

// Modules
import dotenv from "dotenv";
import knex from "knex";
// Environment variables
dotenv.config();
const { PG_HOST, PG_PORT, PG_USER, PG_PASSWORD, PG_DB, APP_MODE } = process.env;
// Connections
const connectionsList = {
production: knex({
client: "pg",
connection: {
host: PG_HOST,
port: (PG_PORT as any),
user: PG_USER,
password: PG_PASSWORD,
database: PG_DB
}
}),
development: knex({
client: "sqlite3",
connection: {
filename: "./development/dev.sqlite3",
database: "dev-db"
}
})
};
// Setting the connection
const connection = connectionsList[APP_MODE as string]; // APP_MODE is a string that can be "production" or "development"
// Export
export default connection;

但这样做会给我一个错误:

元素隐式具有类型"any",因为类型为"string"的表达式不能用于索引类型"{production:Knex<any,unknown[]>;;development:Knex<any,unknown[]>;}"。在类型"{production:Knex<any,unknown[]>;development:Knex<any,unknown[]>;}"中找不到具有"string"类型参数的索引签名。

有办法解决这个问题吗?如果是,如何?如果没有,我应该如何编写代码?

问题是编译器只知道APP_MODEstring(或实际上是string | undefined(,这不足以让编译器确定它是connectionsList的键。据编译器所知,APP_MODE === "testing",然后您正在查找不存在的connectionsList.testing

您可以显式测试APP_MODE,之后编译器会很高兴:

if (APP_MODE !== "production" && APP_MODE !== "development") 
throw new Error("Uh oh, bad APP_MODE");
const connection = connectionsList[APP_MODE]; // okay

或者,您可以断言APP_MODE是这两个值之一,而不是string:

const connection = connectionsList[APP_MODE as "development" | "production"]; // okay

显式测试比断言更安全(因为前者捕获边缘情况,而后者不捕获(,但这两种方法都让编译器知道APP_MODE可以被视为connectionsList的密钥。

游乐场链接到代码

相关内容

  • 没有找到相关文章

最新更新