假设:已经有一个给定的模式定义对象:
const schema = { prop1: { type: String, maxLength: 8 }, prop2... };有没有可能:不需要为每个模式对象声明接口,就可以创建一个相应的类,它可以生成包含从模式中提取的prop1:string, prop2...的文档。
我希望在我的应用程序中会有这样的东西:
// schema definition:
const PersonSchema = { name: { type: String, maxLength: 8 } };
// class factory
const PersonClass = SchemaClassFactory(PersonSchema);
// instance with props defined in schema.
let person1 = new PersonClass();
person1.name = 'Jack';
let person2 = new PersonClass();
person2.name = 3; // should be wrong hinted by tslint.我怎样才能做到这一点呢?
发布于 2018-08-21 15:53:13
您可以使用映射类型和条件类型为架构对象创建一个类,以便从架构中提取对象的形状。
下面是一个可能的解决方案,我不确定我是否涵盖了在mongoose中定义模式的所有方法,但这应该会让您大吃一惊:
const PersonSchema = {
name: { type: String, maxLength: 8 },
age: { type: Number },
title: String,
id: ObjectID
};
type PrimitiveConstructor<T> = {
new (...a: any[]): any;
(...a: any[]): T
}
type Constructor<T> = {
new (...a: any[]): T;
}
type ExtractType<T> = {
[P in keyof T] :
T[P] extends PrimitiveConstructor<infer U>? U :
T[P] extends { type: PrimitiveConstructor<infer U> } ? U:
T[P] extends Constructor<infer U> ? U :
T[P] extends { type: Constructor<infer U> } ? U:
never
}
function createClass<T>(schema: T): new (data?: Partial<ExtractType<T>>) => ExtractType<T> {
// The class will not have the fields explicitly defined since we don't know them but that is fine
return new class {
// Optional constructor for assigning data to the fields, you can remove this if not needed
constructor(data?: any){
if(data) {
Object.assign(this, data);
}
}
} as any;
}
var PersonClass = createClass(PersonSchema);
type PersonClass = InstanceType<typeof PersonClass>
let p = new PersonClass();
p.name ="";
p.name = 2; // error
p.id = new ObjectID(10);
let p2 = new PersonClass({
name: "",
});https://stackoverflow.com/questions/51941718
复制相似问题