在TypeScript中检查字符串是否包含在只读数组中

6
背景是,我正在尝试从.env中读取DatabaseType来构建一个TypeORM连接,代码如下:
const config: ConnectionOptions = {
  type: process.env.DB_CONNECTION, // A type of DatabaseType = 'mysql'|'postgres'|'sqlite'|...
  //...
}

下面是支持的DatabaseType列表:

const SUPPORTED_DB_TYPES = ['mysql', 'mariadb', 'postgres'] as const; // This array contains selected DatabaseType

当我想缩小类型时,问题就出现了。目前这个函数能够工作,但是涉及到类型转换:

const isSupportedDBType = (dbConnection: string|undefined): dbConnection is typeof SUPPORTED_DB_TYPES[number] =>
  dbConnection !== undefined &&
  ((SUPPORTED_DB_TYPES as readonly string[]).indexOf(dbConnection) > -1);

if(!isSupported(process.env.DB_CONNECTION)) {/*...*/}

由于删除 as readonly string[] 后出现以下错误,我必须使用强制类型转换:

参数类型“string”不能赋给参数类型“mysql”|“mariadb”|“postgres”

是否有一种方法可以使用 as readonly string[] 实现呢?

1个回答

1
请注意process.env的类型:
export interface ProcessEnv {
    [key: string]: string | undefined
}

你的问题是由 process.env.DB_CONNECTION 引起的,它是 string | undefined 类型。
所以当你执行这个操作时:
SUPPORTED_DB_TYPES.indexOf(process.env.DB_CONNECTION)

您正在查找一个字符串在一个数组中的位置,该数组包含'mysql' | 'mariadb' | 'postgres'。
解决方案是将DB_CONNECTION类型定义为SUPPORTED_DB_TYPES [number],但这样做是不好的,因为DB_CONNECTION也可能是其他值。或者可以将其转换为任意类型,这也不是一个坏主意。
您的解决方案是使用“as readonly string[]”,在我的看法中也是不错的选择。因为这种转换是局部范围的,并且是由于“indexOf”函数对您的用途过于严格。

3
是的,我知道,所以我正在寻找避免强制转换的方法,因为强制转换并不是很好。 - Daniel Cheung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接