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

How do you check if a type is an array?

答案:你不能

来自 here 我知道要检查一个值是否是一个列表,你可以使用 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(),我想知道是否有某种类型的函数可以在 T 上使用。

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

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

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

    pool = await mysql.createPool(CREDS)
    return pool
}

TypeScript 被转换为 JavaScript,并且 JS 中没有保留 TypeScript 语法(除了枚举等罕见的东西)。您不能让运行的 JavaScript 根据 TypeScript 可以推断出的类型改变其行为。您也需要将逻辑放在 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), but it doesn't look like mysql 实现类似的东西 - 所以没有办法为您缩小传递的查询是否会导致 result 成为数组的范围。(在这里您并不需要它,因为 return 类型看起来并不依赖于它。)