如何检查一个类型是否为数组?

5

回答:你不能这样做

这里我了解到,要检查一个值是否为列表,你可以使用Array.isArray(),但我有一个奇怪的情况,我有一个查询函数

export async function query<T = unknown>(sql: string, options?: unknown): Promise<T> {
    const pool = await initializePool()

    const result = await pool.query(sql, options);
    return /* T is of type list */ ? result : [result];
}

我无法在类型上使用Array.isArray(),我想知道是否有某种typeof函数可以用于T。

问题是,pool.query总是返回一个数组,如果可能的话,我想立即解构它。

const initializePool = async () => {
    if (pool) {
        return pool;
    }

    const CREDS = { connectionLimit: 500000, ...MYSQL_CREDS, multipleStatements: true }

    pool = await mysql.createPool(CREDS)
    return pool
}
1个回答

6

TypeScript会被转译为JavaScript,除了一些罕见的东西(例如枚举),JavaScript中不会保留任何TypeScript语法。您无法根据TypeScript可以推断出的类型来更改JavaScript代码的行为。因此,您需要在JavaScript代码中添加逻辑。

因此,您需要像这样做:

export async function query(sql: string, options?: unknown) {
    const pool = await initializePool()

    const result = await pool.query(sql, options);
    return Array.isArray(result) ? result : [result];
}

理论上,pool.query 可以检查传递的字符串(如果是通用类型),并推断结果是否为数组(参见ts-sql)。但是,看起来mysql没有实现这样的功能 - 因此您无法缩小传递查询将导致 result 是否为数组的范围。(尽管这里不需要,因为返回类型似乎不依赖于它。)


唯一的问题是 pool.query 始终返回 RowDataPacket 列表,这意味着您的解决方案不起作用。不幸的是,我认为我只能咬紧牙关,接受它总是返回一个数组,并在需要时提取第一个索引。 - DucksEatTurtles

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