Curious Question: Can a class be created based on a specific prototype?

Imagine you have an existing schema definition object like this:

const schema = { prop1: { type: String, maxLength: 8 }, prop2... };

Now, the challenge is to create a class that can generate documents using properties extracted from the schema without having to declare an interface for each schema object. Is it possible?

You might want something similar to the following in your application:

// 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; // This should be flagged as an error by tslint.

How can you achieve this functionality efficiently?

Answer №1

If you want to generate a class for the schema object by using mapped types and conditional types to extract the structure of the object from the schema, one approach is detailed below. It may not cover all possible ways of defining the schema in mongoose, but it serves as a good starting point:

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: "",
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When using the Angular checkbox, remember to keep one box checked at all times

When my page loads, there are two checkboxes: Active and InActive. By default, both are checked (true) and the user has the ability to uncheck either one, but not both at the same time. To handle this situation, I implemented a getter method to retrieve t ...

Is the transcluded content visible to the class as a whole?

Angular2 makes it simple to create a component like this: @Component({ selector: 'some', properties: ['header'] }) @View({ template: ` <div> <h2>{{ getFormattedHeader() }}</h2> <p><conte ...

Tips for accessing attributes within an array of objects using Handlebars

Currently, I'm in the process of developing a thrilling Treasure Hunt application that features a scoreboard. Within the scoreboard route, I am using asynchronous function calls to fetch JSON data from MongoDB. The resulting data structure is as follo ...

Is it possible to encounter a MongoDB error for the $or operator in a correctly formatted query?

Here is the problem I am facing: const users = this.mongo.db.collection('Users') let query = { '$or': [ { "email": {'$eq': req.body.email }}, {"username": {'$eq': req.body.username }} ] } users.fi ...

Here's a way to resolve the issue: ReactDOM.render() - TS2345 error: Cannot assign type '() => Element' to type 'ReactElement' in the argument

After tackling React-Router with Typescript, I encountered a typing issue that has me perplexed. Prior to this, I was using an older version of React and React-Router. But now, after updating to the latest builds using yarn, I'm facing this hurdle. ...

When trying to upload a file with ng-upload in Angular, the error 'TypeError: Cannot read properties of undefined (reading 'memes')' is encountered

Struggling with an issue for quite some time now. Attempting to upload an image using ng-upload in angular, successfully saving the file in the database, but encountering a 'Cannot read properties of undefined' error once the upload queue is comp ...

Is it feasible to invoke a method without any arguments on this basic subscription?

A BRIEF SUMMARY Implementing an observable in my code, I strive for maintaining cleanliness and efficiency by utilizing the detectChanges() method to update *ngIf= in the HTML. QUERY Is there a way to invoke the detectChanges() method within subscribe() ...

Unable to remove element from database using Mongoose $pull

I am facing a challenge when trying to transfer an entry from one array to another within the same collection using $pull and $push. While $push works as expected, I encounter issues with $pull not removing the array element. The code snippet I am current ...

Transforming the MongoDB project into a collection

I have a collection of nested objects in an array and need to extract specific elements from these objects and return them in a new array. The sample document structure is as follows: "detailLine": [ { "name": "first", "value": { ...

Retrieving data from multiple collections using Mongoose

In my nodejs application, I am looking to retrieve data in the format specified below. The models used are user.js and userProfile within mongoose. user.js var userSchema = new Schema({ nick_name:{type:String}, email: {type: Strin ...

Efficient method for performing bulk delete operations in MongoDB aggregation with Python

I am seeking a more efficient way to delete data from multiple collections based on IDs received using a match query from aggregation methods. Currently in my Python code, I am handling this process, but it is proving to be time-consuming. The motor is be ...

How can you determine the data types of properties within a blank class object using Typescript and Angular?

Class Example{ constructor( public x: number, public y: string ) {} } let e = new Example(); Is there a way to programmatically determine the data type of e.x or e.y in TypeScript? ...

Declaring module public type definitions for NPM in Typescript: A comprehensive guide

I have recently developed a npm package called observe-object-path, which can be found on GitHub at https://github.com/d6u/observe-object-path. This package is written in Typescript and has a build step that compiles it down to ES5 for compatibility with ...

Guide to organizing a MongoDB query based on the ratio of two fields within each document

Imagine having numerous documents in the format {'a': x, 'b': y}. Let's assume x and y are both integers. How can I achieve a task similar to performing find().sort({'a'/'b'})? ...

Incorrect deduction of the argument type for a higher-order function

If I wanted to create a function that takes an object of type T and another value, where the type P should somehow be restricted by T (for example, P should be an array of keys of T), I could easily write it like this: function customFunction<T, P exte ...

Combine and transform two files using array structures

Here is the input data: [ { "_id" : ObjectId("xxx"), "ParentNumber" : "12345", "ChildNumber" : "A123" }, { "_id" : ObjectId("yyy"), ...

The connection between Mongoose and the nodejs app cannot be established

I've been attempting to integrate Mongoose with my Node.js environment, but I'm encountering an unexpected error. Previously, I was able to connect with Mongoose using the same commands, but for the past few days, it's been throwing errors. ...

"Add a pre-hook in mongoose to update a field in findOneAndUpdate by retrieving data from a

I’m attempting to make modifications to a document in the findOneAndUpdate pre-hook. The code for this operation is provided below. userSchema.pre('findOneAndUpdate', function (next) { // this._update.$set //var user = new User(this._update.$s ...

What is the method for inserting an object into a jsonArray in TypeScript?

I am trying to add an object to existing JSON data in TypeScript. I am new to TypeScript and have created an array variable called jsonArrayObject, which contains a boolean[] type. This jsonArrayObject holds a contactModel object with properties like fname ...

The maximum nested function level has been reached at tsc:1. Consider increasing the FUNCNEST limit

Having an issue while trying to compile a typescript file, encountering the following error: work/gigMax [typescriptMigration●] » tsc src/mutate.ts tsc:1: maximum nested function level reached; increase FUNCNEST? work/gigMax [typescriptMigration●] ...