Mongoose,如何强制LeanDocument类型?

cunj1qz1  于 2023-06-06  发布在  Go
关注(0)|答案(1)|浏览(119)

在我们的代码库中,我们一直使用T.lean()T.toObject(),我们的返回类型将是LeanDocument<T>。Mongoose 7不再导出LeanDocument,现有的迁移指南建议使用以下设置:

// Do this instead, no `extends Document`
interface ITest {
  name?: string;
}
const Test = model<ITest>('Test', schema);

// If you need to access the hydrated document type, use the following code
type TestDocument = ReturnType<(typeof Test)['hydrate']>;

但这给了我HydratedDocument,我可以通过HydratedDocument<T>得到,这不是我想要的,因为它有所有的文档方法。
作为替代,我可以只使用T作为我的返回类型,但任何Document<T>都匹配T
我想强制执行结果是POJO,以防止文件从我们的DAL泄漏。
我怎样才能用typescript和mongoose类型实现这一点呢?

qco9c6ql

qco9c6ql1#

在mongoose repo上问了一个类似的问题,我决定采用以下方法:

// utils.ts
export type LeanDocument<T> = T & { $locals?: never };

因此,在下面的情况下,typescript会提醒我不能返回文档:

async function getById(id: string): Promise<LeanDocument<User>> {
  const user = await UserModel.findById(id);
  return user;
  //       ^ Types of property '$locals' are incompatible.
}

我认为这可以通过更清楚的类型错误来进一步改进,该类型错误将沿着Type error ... "You've forgot to convert to a lean document".的路线声明一些东西,就像我以前在库中看到的那样。
但我还没找到方法:)

编辑

一些打字脚本魔术:

export type LeanDocument<T> = T & T extends { $locals: never }
  ? T
  : 'Please convert the document to a plain object via `.toObject()`';

将导致以下错误:

async function getById(id: string): Promise<LeanDocument<User>> {
  const user = await UserModel.findById(id);
  return user;
  //       ^ Type 'Document<unknown, any, User> & Omit<User & { _id: ObjectId; }, never>'
  // is not assignable to type 
  // '"Please convert the document to a plain object via `.toObject()`"'.ts(2322)
}

相关问题