Typescript like intellisense for simple schema?


#1

I am used to have extensive intellisense autocompletion in my projects (nuxt,js with typescript)
I normally create models (classes) that I can then use everywhere to interact with my data entities.
Using simpleschema it seems redundant to define all attributes for my dataschema using simple schema and then again with typescript for separate models that copy the simple schema structure.

Is there some way get autocompletion for meteor collections that have a simple-schema attached?


#2

For anyone interested:

I now have a solution with a little typing overhead, but it works:

I define a class and attach a simple schema to it. I then manually call the simpleschema validate method on the class whenever required. This requires me to define all properties twice to get intellisense (for simpleschema & the class itself)


#3

Can you post a quick example? I’d love to do this too


#4
class User {
    name: string
    schema = new SimpleSchema({name: String})

    get isValid() {
        this.schema.validate({ ...this})
        return this.schema.isValid()
    }

    save() {
        if(!this.isValid) {
            throw new Error(this.schema.validationErrors())
        }
        // persist the instance 
    }
}

#5

Thanks!

Could this class extend Mongo.Collection and check for validity before calling super.method?
Or are you using it more like a traditional ORM?


#6

There is no need to extend the class if it’s just for validity checking. You can attach the schema directly to the collection. So you wouldn’t need the wrapping class.

However, extending it could help with intellisense for queries:


interface UserProperties {
    name: string
    city ?: string
}

class User implements UserProperties {
    constructor(args: UserProperties ) {
        for (let key in args) {
            this[key] = args[key]
        }
    }
}

class UserCollection extends Mongo.Collection {
    schema = new SimpleSchema({name: String, city: {type: String, optional: true})

    contructor(args: any) {
        super(args)
        this.attachSchema(this.schema)
    }

    insert(args: UserProperties) {
        return super.insert(args)
    }

   update(id: string, args: Partial<UserProperties>) {
       return super.update(id, { $set: args })
   }
  
   find(args: any) {
       documents = super.find(args)
       users: User[] =[]
       for(let doc in documents) {
           users.push(new User(doc))
       }
       return users
   }
}