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

