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

条件键重映射为何无法过滤attribute为true的键?

根据类布尔属性过滤对象键的问题分析与解决

问题原因

你的代码里,Test类的attribute属性被定义为宽泛的boolean类型,而非具体的true/false字面量类型。尽管运行时test1的attribute是true、test2是false,但在TypeScript类型系统中,所有Test实例的attribute类型都是boolean。

这导致映射类型里的条件T[K]['attribute'] extends true ? never : K无法区分两个键——因为boolean并不继承自true,所以条件对两个键都返回K,最终所有键都被保留下来。

解决方案

方案一:使用泛型类推断属性字面量类型

修改Test类为泛型类,让构造函数根据传入的参数自动推断attribute的具体字面量类型:

class Test<T extends boolean = true> {
  readonly attribute: T;

  constructor(attribute?: T) {
    this.attribute = attribute ?? (true as T);
  }
}

type TestType2<T extends Record<string, Test<boolean>>> = {
  [K in keyof T as T[K]['attribute'] extends true ? never : K]: number;
};

const a = {
  test1: new Test(), // attribute类型为true
  test2: new Test(false), // attribute类型为false
};

type FinalTest = TestType2<typeof a>; // 结果为{ test2: number },符合预期

方案二:通过类型断言指定实例属性类型

如果无法修改Test类的定义,可以给每个实例添加类型断言,明确attribute的具体字面量类型:

class Test {
  readonly attribute: boolean;

  constructor(attribute?: boolean) {
    this.attribute = attribute ?? true;
  }
}

type TestType2<T extends Record<string, Test>> = {
  [K in keyof T as T[K]['attribute'] extends true ? never : K]: number;
};

const a = {
  test1: new Test() as Test & { attribute: true },
  test2: new Test(false) as Test & { attribute: false },
};

type FinalTest = TestType2<typeof a>; // 结果为{ test2: number }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:03:15