使用infer提取Typegoose原始文档类型返回unknown的问题
解决Mongoose Document原始类型提取返回unknown的问题
问题分析
你定义的ObtainRawDocType泛型意图提取Mongoose Document的原始文档类型,但调用clearFields后返回类型被识别为unknown,核心原因是泛型推断没有正确捕获到Document的第三个类型参数(即原始文档类型)——当T被推断为mongoose.Document时,其默认类型参数未被显式传递,导致infer C无法正确解析出目标类型。
解决方案
方案1:显式约束泛型并推断原始文档类型
调整clearFields的泛型定义,直接从T的类型约束中推断原始文档类型,避免间接推断的不确定性:
import mongoose from "mongoose"; // 改进类型提取逻辑 type ObtainRawDocType<T extends mongoose.Document<any, any, infer C>> = C; export function clearFields< T extends mongoose.Document<any, any, infer DocType>, U extends PropertyKey[] >(dataObj: T, privateFields: U): ObtainRawDocType<T> { // 将Document转为原始对象并过滤字段 const rawDoc = { ...dataObj.toObject() } as DocType; privateFields.forEach(field => delete rawDoc[field as keyof DocType]); return rawDoc; }
方案2:使用Mongoose内置类型工具
Mongoose提供了内置的类型工具Types.DocumentType,可以更可靠地从Model或Document实例中提取原始文档类型:
import mongoose, { Types } from "mongoose"; type ObtainRawDocType<T> = T extends Types.DocumentType<infer U> ? U : never; export function clearFields< T extends mongoose.Document, U extends PropertyKey[] >(dataObj: T, privateFields: U): ObtainRawDocType<T> { const rawDoc = dataObj.toObject() as ObtainRawDocType<T>; privateFields.forEach(field => delete rawDoc[field as keyof typeof rawDoc]); return rawDoc; }
生效原理
两种方案都通过明确约束泛型参数的传递路径,让TypeScript能正确捕获Mongoose Document关联的原始文档类型,避免了默认类型参数导致的unknown推断结果。调用clearFields(c1, ["birthdate"])时,cc1的类型会被正确解析为你的原始文档类型(比如定义的User接口)。
内容的提问来源于stack exchange,提问作者aderchox
相关产品推荐
相关产品推荐

