You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何根据数组元素顺序推断回调函数参数类型

解决方案

要实现回调参数与传入数组元素的类型按顺序自动对应,核心是让TypeScript将传入的数组推断为元组类型(而非普通的联合类型数组),这样泛型就能精准映射每个位置的类型。

关键问题分析

原代码中,传入['hello', 2]时,TypeScript默认会将其推断为(string | number)[],导致fetcher的参数类型变为string | number的联合类型,无法按顺序匹配具体类型。

修正后的代码

const fetcher = async(arg1: string, arg2: string): Promise<string | boolean> => {
    try {
        return arg1 + ' - ' + arg2
    } catch(e) {
        return false
    }
}

// 调整Fetcher类型,让参数与元组A严格对应
type Fetcher<A extends readonly any[], T> = (...args: A) => Promise<T>

const useAdminEndpoint = <A extends readonly any[], T>(
    // 使用可变元组语法[...A],强制推断为元组
    key: [...A],
    fetcher: Fetcher<A, T>
) => {
    const run = async() => {
        try {
            // 用扩展运算符替代apply,类型更安全
            return await fetcher(...key)
        } catch(e) {
            // 明确返回false的类型,避免类型混淆
            return false as false
        }
    }
    // 返回执行结果(原代码中result未定义,这里修正为返回run的异步结果)
    return run()
}

// 现在回调参数h和g会自动对应数组元素的具体类型
// 注意:因为fetcher要求第二个参数是string,这里传入2(number)会触发类型错误,符合预期
const result = useAdminEndpoint(['hello', 2], (h, g) => fetcher(h, g))

核心优化点

  1. 可变元组语法:通过key: [...A]强制TypeScript将数组字面量推断为元组,保留每个元素的具体类型,而非合并为联合类型。
  2. 泛型约束调整:让泛型A继承readonly any[],确保支持只读元组的推断。
  3. 类型安全调用:使用扩展运算符...key传递参数,比apply更直观且符合TypeScript的类型检查规则。

内容的提问来源于stack exchange,提问作者Thomas Huxley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 02:05:35