首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有趣的挑战:根据给定的原型制作一个类是可能的吗?

有趣的挑战:根据给定的原型制作一个类是可能的吗?
EN

Stack Overflow用户
提问于 2018-08-21 12:47:46
回答 1查看 63关注 0票数 1

假设:已经有一个给定的模式定义对象:

代码语言:javascript
复制
const schema = { prop1: { type: String, maxLength: 8 }, prop2... };

有没有可能:不需要为每个模式对象声明接口,就可以创建一个相应的类,它可以生成包含从模式中提取的prop1:string, prop2...的文档。

我希望在我的应用程序中会有这样的东西:

代码语言:javascript
复制
// 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.

我怎样才能做到这一点呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-21 15:53:13

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

下面是一个可能的解决方案,我不确定我是否涵盖了在mongoose中定义模式的所有方法,但这应该会让您大吃一惊:

代码语言:javascript
复制
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: "",
});
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51941718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档