Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 感兴趣的挑战:是否可以根据给定的原型创建一个类?_Mongodb_Typescript - Fatal编程技术网

Mongodb 感兴趣的挑战:是否可以根据给定的原型创建一个类?

Mongodb 感兴趣的挑战:是否可以根据给定的原型创建一个类?,mongodb,typescript,Mongodb,Typescript,假设:已存在给定的架构定义对象: const schema = { prop1: { type: String, maxLength: 8 }, prop2... }; 有没有可能:在不声明每个模式对象的接口的情况下,创建一个相应的类,该类可以生成从模式中提取的prop1:string,prop2…文档 我希望在我的应用程序中有类似的内容: // schema definition: const PersonSchema = { name: { type: String, maxLength:

假设:已存在给定的架构定义对象:

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.

如何实现这一点?

您可以使用映射类型和条件类型为模式对象创建一个类,以从模式中提取对象的形状

下面是一个可能的解决方案,我不确定我介绍了在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: "",
});
const PersonSchema={
名称:{type:String,maxLength:8},
年龄:{type:Number},
标题:字符串,
id:ObjectID
};
类型基本构造函数={
新(…a:any[]):any;
(…a:any[]):T
}
类型构造函数={
新(…a:any[]):T;
}
类型提取类型={
[P in keyof T]:
T[P]扩展了基元构造函数?U:
T[P]扩展了{type:PrimitiveConstructor}?U:
T[P]扩展构造函数?U:
T[P]扩展了{type:Constructor}?U:
从未
}
函数createClass(模式:T):新建(数据?:部分)=>ExtractType{
//该类不会显式定义字段,因为我们不知道它们,但这很好
返回新类{
//用于将数据分配给字段的可选构造函数,如果不需要,可以删除此构造函数
构造函数(数据?:任何){
如果(数据){
分配(此,数据);
}
}
}如有的话;
}
var PersonClass=createClass(PersonSchema);
type PersonClass=InstanceType
设p=newpersonclass();
p、 name=“”;
p、 name=2;//错误
p、 id=新对象id(10);
设p2=新PersonClass({
姓名:“,
});

为什么要声明一个不同于标准类的类?架构定义对象将导出到另一个第三方模块,该模块将使用它来验证插入数据。您太棒了!真的。@DC 10x,我确实有史诗徽章,现在就去传奇徽章;-)还有两种类型:一种是类似于[String]、[Foo]的数组。。。另一个是类似于[1,4,'a']的枚举。@DC我将为这些添加casse。。。。在我的手机上,因为我刚去度假,所以可能需要一段时间:-)