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

TypeScript类Prisma风格条件返回类型未按预期工作

问题原因

你的代码无法触发预期错误的核心原因是**defaultResolveQueryOptions的类型被宽泛化了**:

  • 你显式给它标注了ResolveQueryOptions类型,这个类型的属性是boolean(而非具体的true/false字面量)。
  • 当传入example函数时,TypeScript推导的泛型T是ResolveQueryOptions,而非你期望的{group: true; user: false}。
  • 此时SelectKeys<T>的判断逻辑T[K] extends false ? never : K无法过滤掉user,因为boolean类型可能是true或false,TypeScript无法确定其具体值,因此会保留所有键。
解决方案

方案1:移除显式类型标注,让TypeScript自动推导字面量类型

直接去掉defaultResolveQueryOptions的类型标注,TypeScript会自动推导它的字面量类型{group: true; user: false}:

const defaultResolveQueryOptions = {
  group: true,
  user: false,
};

方案2:使用as const断言 + satisfies保留类型约束

如果需要确保对象符合ResolveQueryOptions结构,同时保留字面量类型,可以用satisfies结合as const:

const defaultResolveQueryOptions = {
  group: true,
  user: false,
} as const satisfies ResolveQueryOptions;

方案3:优化函数泛型约束(可选)

为了避免宽泛的boolean类型传入函数,可将泛型约束调整为强制字面量布尔值:

function example<T extends Record<keyof ResolveQueryOptions, true | false>>(options: T): QueryResult<T> {
  const a: any = {};

  if (options.group) {
    a.result.group = [] as Group[];
  }
  if (options.user) {
    a.result.user = [] as User[];
  }

  return a as QueryResult<T>;
}
优化类型逻辑(可选)

原SelectKeys的判断逻辑可以更精准,直接筛选值为true的键:

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

修复后,result.result.user会触发预期的TS错误,因为此时QueryResult<T>的result对象仅包含group属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:05:39