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

TypeScript中for-of上下文里Iterable返回类型不符合预期的问题

泛型函数中obj1与obj2类型差异的原因

首先看你的代码:

interface A  {
    Id: string,
    Level: number,
    IA1: string,
    IA2: string,
    IA3: string,
    IA4: string,
}
interface B  {
    Id: string,
    Level: number,
    IA1: string,
    IA2: string,
    IA3: string,
}
interface C {
    Id: string,
    Level: number,
}
type Player = {
    A: Iterable<[A, number]>,
    B: Iterable<[B, number]>,
    C: Iterable<[C, number]>,
}
function find<T extends "A" | "B" | "C">(player: Player, type: T) {
    for(const [obj1] of player[type]){
        // obj1的类型是 A & B & C(仅包含Id、Level属性)
    }
    let t1 : "A" | "B" | "C" = type as any
    for(const [obj2] of player[t1]){
        // obj2的类型是 A | B | C
    }
}

两者类型差异的核心原因在于TypeScript对泛型参数与显式联合类型的处理逻辑不同:

  • 对于obj1:
    type是泛型参数T,它的约束是"A"|"B"|"C",但在函数内部,TypeScript将T视为一个单一的、尚未确定的具体类型(比如调用函数时传入的是"A",那T就是"A";传入"B"就是"B")。因此player[type]对应的是Player[T],也就是某个特定键对应的迭代器类型,而非三者的联合。

    由于TypeScript无法在函数内部确定T的具体值,它会取所有可能的Player[T]元素类型的交集——也就是同时属于A、B、C的类型。因为三个接口的共同属性只有Id和Level,所以obj1的类型最终被推断为仅包含这两个属性的交集类型。

  • 对于obj2:
    t1是显式声明的联合类型"A"|"B"|"C",此时player[t1]的类型是三个迭代器类型的联合:Iterable<[A, number]> | Iterable<[B, number]> | Iterable<[C, number]>。

    当迭代联合类型的迭代器时,TypeScript会将元素类型推断为对应元素类型的联合,也就是A | B | C,这就是obj2呈现该类型的原因。

内容的提问来源于stack exchange,提问作者Eighteen Liang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:10:14