You need to enable JavaScript to run this app. 如何告知TypeScript两个泛型类型为同一类型?
优惠活动
大模型
产品
解决方案
定价
更多

如何告知TypeScript两个泛型类型为同一类型?

解决方案

你遇到的类型报错本质是TypeScript无法在函数实现内部自动根据重载分支收窄泛型类型,即使你定义了无init参数的重载,TS也无法推导该场景下泛型B和A是同一类型。可以通过重载分离场景+内部类型断言的方式解决,不会影响外部调用的类型安全性:

改后完整代码

// 重载1:无init参数,累计值类型和数组元素类型一致
function scan<A>(this: A[], f: (a: A, x: A) => A): A[];
// 重载2:传入init参数,可自定义累计值类型
function scan<A, B>(this: A[], f: (a: B, x: A) => B, init: B): B[];
// 实现签名:兼容两个重载的类型范围即可
function scan<A, B>(this: A[], f: (a: A | B, x: A) => A | B, init?: B): (A | B)[] {
    if (init === undefined) {
        const result = [this[0]];
        // 断言当前场景下回调符合A类型约束,和第一个重载逻辑对应
        const accumulator = f as (a: A, x: A) => A;
        for (let i = 1; i < this.length; i++) {
            result.push(accumulator(result[i - 1], this[i]));
        }
        return result;
    }

    const result = [init];
    // 断言当前场景下回调符合B类型约束,和第二个重载逻辑对应
    const accumulator = f as (a: B, x: A) => B;
    for (let i = 0; i < this.length; i++) {
        result.push(accumulator(result[i], this[i]));
    }
    return result;
}

说明

  • 把第二个重载的init从可选改为必选,避免出现调用方传了回调但init传undefined的不合法场景,类型更严谨
  • 内部的类型断言是安全的,因为重载已经对外约束了两种调用场景的参数类型,实现逻辑和重载完全对齐,不会出现类型错误
  • 外部调用时类型推导完全正常,无init时自动推断返回值为A[],传init时自动根据init类型推断B的类型

内容的提问来源于stack exchange,提问作者Aadit M Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 05:06:06