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

如何在TypeScript中实现Options类型的联合键约束?

TypeScript约束item为obj1或obj2的键的实现方案

你遇到的问题根源在于TypeScript的泛型推断优先级:原代码中t1和t2的推断会优先匹配item的类型,而不是先从obj1、obj2的键推断泛型。当传入item: 'white'时,TypeScript会认为t1 | t2 = 'white',进而将t1和t2都推断为'white',导致obj1的键被限制为'white',与实际传入的red、green冲突,所以报错。

方案1:用泛型捕获obj1和obj2的完整类型

直接让泛型参数捕获obj1和obj2的具体类型,再通过keyof约束item的取值范围:

declare function f<T1 extends Record<string, any>, T2 extends Record<string, any>>(
  opts: { 
    obj1: T1; 
    obj2: T2; 
    item: keyof T1 | keyof T2 
  }
): void;

// 符合预期,无报错
f({
  obj1: { red: null, green: null },
  obj2: { black: null, white: null },
  item: 'white'
});

// 非法输入会触发类型错误(item不在允许的键中)
f({
  obj1: { red: null },
  obj2: { black: null },
  item: 'blue' // 类型错误:"blue"不能赋值给"red" | "black"
});

方案2:用交叉类型约束单一泛型参数

如果希望用单一泛型参数,也可以通过交叉类型将obj的类型与item的约束结合:

declare function f<O extends { obj1: Record<string, any>, obj2: Record<string, any> }>(
  opts: O & { item: keyof O['obj1'] | keyof O['obj2'] }
): void;

// 同样可以正常工作
f({
  obj1: { red: null, green: null },
  obj2: { black: null, white: null },
  item: 'white'
});

为什么这两种方案可行?

这两种方案都改变了泛型推断的顺序:TypeScript会先推断obj1和obj2的具体类型(或泛型O的结构),再基于这些类型推导item的合法取值范围,完全符合你预期的逻辑——先确定obj1、obj2的键,再约束item必须是其中之一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:47:26