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
相关产品推荐
相关产品推荐

