Handling Subdocuments in TypeScript用TypeScript处理子文档

Subdocuments are tricky in TypeScript. By default, Mongoose treats object properties in document interfaces as nested properties rather than subdocuments.TypeScript中的子文档很棘手。默认情况下,Mongoose将文档接口中的对象属性视为嵌套属性,而不是子文档。

// Setup
import { Schema, Types, model, Model } from 'mongoose';

// Subdocument definition子文档定义
interface Names {
_id: Types.ObjectId;
firstName: string;
}

// Document definition文件定义
interface User {
names: Names;
}

// Models and schemas模型和模式
type UserModelType = Model<User>;
const userSchema = new Schema<User, UserModelType>({
names: new Schema<Names>({ firstName: String })
});
const UserModel = model<User, UserModelType>('User', userSchema);

// Create a new document:创建新文档:
const doc = new UserModel({ names: { _id: '0'.repeat(24), firstName: 'foo' } });

// "Property 'ownerDocument' does not exist on type 'Names'."“类型'Names'上不存在属性'ownerDocument'。”
// Means that `doc.names` is not a subdocument!意味着文档名称不是子文档!
doc.names.ownerDocument();

Mongoose provides a mechanism to override types in the hydrated document. Mongoose提供了一种机制来覆盖水合文档中的类型。The 3rd generic param to the Model<> is called TMethodsAndOverrides: originally it was just used to define methods, but you can also use it to override types as shown below.Model<>的第三个通用参数称为TMethodsAndOverrides:最初它只是用来定义方法,但您也可以使用它来覆盖类型,如下所示。

// Define property overrides for hydrated documents为水合文档定义属性重写
type UserDocumentOverrides = {
names: Types.Subdocument<Types.ObjectId> & Names;
};
type UserModelType = Model<User, {}, UserDocumentOverrides>;

const userSchema = new Schema<User, UserModelType>({
names: new Schema<Names>({ firstName: String })
});
const UserModel = model<User, UserModelType>('User', userSchema);


const doc = new UserModel({ names: { _id: '0'.repeat(24), firstName: 'foo' } });
doc.names.ownerDocument(); // Works, `names` is a subdocument!有效,`names`是一个子文档!

Subdocument Arrays子文档阵列

You can also override arrays to properly type subdocument arrays using TMethodsAndOverrides:您也可以使用TMethodsAndOverrides重写数组以正确键入子文档数组:

// Subdocument definition子文档定义
interface Names {
_id: Types.ObjectId;
firstName: string;
}
// Document definition文件定义
interface User {
names: Names[];
}

// TMethodsAndOverrides
type UserDocumentProps = {
names: Types.DocumentArray<Names>;
};
type UserModelType = Model<User, {}, UserDocumentProps>;

// Create model创建模型
const UserModel = model<User, UserModelType>('User', new Schema<User, UserModelType>({
names: [new Schema<Names>({ firstName: String })]
}));

const doc = new UserModel({});
doc.names[0].ownerDocument(); // Works!