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

TypeScript映射类型:如何根据值条件移除指定键?

优化映射类型实现 + 解答never属性的困惑

首先,先解决你关于{ key: never }的困惑:TypeScript中,即使属性的类型是never,这个属性依然会保留在类型结构中——它只是意味着没有任何值可以赋值给这个属性(因为never没有子类型),但类型本身仍然包含这个键。如果想要省略某个键,需要通过条件类型主动不包含它,或者用Omit工具类型移除它。

接下来,针对你的需求,我们可以优化掉交叉类型,用更直观的条件分支直接生成目标类型:

type DataParams = {
  trade: never;
  trade_bar: { 
    interval: number; 
    intervalUnit: "ms" | "s" | "m" | "ticks" | "vol"; 
  };
};
type DataTypes = keyof DataParams;

// 直接通过条件分支返回带/不带params的结构
type OptionsForDataType<T extends DataTypes> = 
  DataParams[T] extends never
    ? { type: T }
    : { type: T; params: DataParams[T] };

// 利用条件类型的自动分发特性,直接生成联合类型
type Options = OptionsForDataType<DataTypes>;

这个写法的优势在于:

  • 完全避免了交叉类型,逻辑更直白:当DataParams[T]是never时,只返回{ type: T };否则返回包含params的完整结构。
  • 利用TypeScript条件类型的联合分发特性:当T是联合类型(DataTypes)时,OptionsForDataType<DataTypes>会自动遍历联合中的每个成员,生成对应的子类型,最终合并成你需要的联合类型,效果和你之前的映射类型索引访问完全一致。

如果你偏好映射类型的写法,也可以用as子句来过滤属性,但上面的条件分支写法已经足够简洁了。

另外,再补充一点:如果你的场景更复杂,需要在已有类型上动态移除never类型的属性,可以用下面的工具类型:

type OmitNeverProperties<T> = {
  [K in keyof T as T[K] extends never ? never : K]: T[K];
};

这个类型会遍历T的所有键,把类型为never的键过滤掉,比如OmitNeverProperties<{ type: 'trade'; params: never }>会得到{ type: 'trade' }。不过在你的场景中,前面的条件分支写法已经更直接了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 21:22:29