diff --git a/src/database.ts b/src/database.ts index 7cd65c7..8d8d031 100644 --- a/src/database.ts +++ b/src/database.ts @@ -118,7 +118,7 @@ class Database { * @param {Schema|object} [schema] * @return {Model} */ - model(name: string, schema?: Schema | Record): Model { + model(name: string, schema?: Schema | Record): Model { if (this._models[name]) { return this._models[name]; } diff --git a/src/document.ts b/src/document.ts index 8ac24ff..e6d12e7 100644 --- a/src/document.ts +++ b/src/document.ts @@ -8,7 +8,7 @@ const cloneDeep = rfdc(); abstract class Document { abstract _model: Model; _id!: string | number | undefined; - abstract _schema: Schema; + abstract _schema: Schema; [key : string]: any; /** diff --git a/src/model.ts b/src/model.ts index 2cc03f0..a61fef5 100644 --- a/src/model.ts +++ b/src/model.ts @@ -16,7 +16,7 @@ import type { AddSchemaTypeOptions, NodeJSLikeCallback, Options, PopulateResult class Model extends EventEmitter { _mutex = new Mutex(); data: Record = {}; - schema: Schema; + schema: Schema; length = 0; Document; Query; @@ -28,10 +28,10 @@ class Model extends EventEmitter { * @param {string} name Model name * @param {Schema|object} [schema_] Schema */ - constructor(public name: string, schema_: Schema | Record) { + constructor(public name: string, schema_: Schema | Record) { super(); - let schema: Schema; + let schema: Schema; // Define schema if (schema_ instanceof Schema) { @@ -51,7 +51,7 @@ class Model extends EventEmitter { class _Document extends Document { _model!: Model; - _schema!: Schema; + _schema!: Schema; constructor(data: T) { super(data); @@ -67,7 +67,7 @@ class Model extends EventEmitter { class _Query extends Query { _model!: Model; - _schema!: Schema; + _schema!: Schema; } this.Query = _Query; @@ -963,7 +963,7 @@ class Model extends EventEmitter { Model.prototype.get = Model.prototype.findById; -function execHooks(schema: Schema, type: string, event: string, data: any): BluebirdPromise { +function execHooks(schema: Schema, type: string, event: string, data: any): BluebirdPromise { const hooks = schema.hooks[type][event] as ((data: any) => BluebirdPromise | void)[]; if (!hooks.length) return BluebirdPromise.resolve(data); diff --git a/src/query.ts b/src/query.ts index c5fe5eb..93ba80c 100644 --- a/src/query.ts +++ b/src/query.ts @@ -9,7 +9,7 @@ abstract class Query { data: Document[]; length: number; abstract _model: Model; - abstract _schema: Schema; + abstract _schema: Schema; /** * Query constructor. diff --git a/src/schema.ts b/src/schema.ts index 64fe5f2..f6814a5 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -6,6 +6,8 @@ import PopulationError from './error/population'; import SchemaTypeVirtual from './types/virtual'; import { isPlainObject } from 'is-plain-object'; import type { AddSchemaTypeLoopOptions, AddSchemaTypeOptions, PopulateResult, SchemaTypeOptions } from './types'; +import type Model from './model'; +import type Document from './document'; /** * @callback queryFilterCallback @@ -379,10 +381,10 @@ class QueryParser { } -class Schema { +class Schema { paths: Record> = {}; - statics: Record any> = {}; - methods: Record any> = {}; + statics: Record, ...args: any[]) => any> = {}; + methods: Record any> = {}; hooks: { pre: { save: ((...args: any[]) => BluebirdPromise)[] @@ -557,7 +559,7 @@ class Schema { * @param {Function} [getter] * @return {SchemaType.Virtual} */ - virtual(name: string, getter?: () => any): SchemaTypeVirtual { + virtual(name: string, getter?: (this: T) => any): SchemaTypeVirtual { const virtual = new Types.Virtual(name, {}); if (getter) virtual.get(getter); @@ -598,7 +600,7 @@ class Schema { * @param {String} name * @param {Function} fn */ - method(name: string, fn: (...args: any[]) => any) { + method(name: string, fn: (this: T, ...args: any[]) => any) { if (!name) throw new TypeError('Method name is required!'); if (typeof fn !== 'function') { @@ -614,7 +616,7 @@ class Schema { * @param {String} name * @param {Function} fn */ - static(name: string, fn: (...args: any[]) => any) { + static(name: string, fn: (this: Model, ...args: any[]) => any) { if (!name) throw new TypeError('Method name is required!'); if (typeof fn !== 'function') { diff --git a/src/types/virtual.ts b/src/types/virtual.ts index 383907b..1a64aef 100644 --- a/src/types/virtual.ts +++ b/src/types/virtual.ts @@ -4,8 +4,8 @@ import { setGetter } from '../util'; /** * Virtual schema type. */ -class SchemaTypeVirtual extends SchemaType { - getter: (() => any) | undefined; +class SchemaTypeVirtual extends SchemaType { + getter: ((this: T) => any) | undefined; setter: ((value: any) => void) | undefined; /** @@ -14,7 +14,7 @@ class SchemaTypeVirtual extends SchemaType { * @param {Function} fn * @chainable */ - get(fn: () => any): SchemaTypeVirtual { + get(fn: (this: T) => any): SchemaTypeVirtual { if (typeof fn !== 'function') { throw new TypeError('Getter must be a function!'); } @@ -30,7 +30,7 @@ class SchemaTypeVirtual extends SchemaType { * @param {Function} fn * @chainable */ - set(fn: (value: any) => void): SchemaTypeVirtual { + set(fn: (this: T, value: any) => void): SchemaTypeVirtual { if (typeof fn !== 'function') { throw new TypeError('Setter must be a function!'); } diff --git a/test/scripts/model.ts b/test/scripts/model.ts index df03eaf..3d9b59d 100644 --- a/test/scripts/model.ts +++ b/test/scripts/model.ts @@ -37,7 +37,15 @@ describe('Model', () => { const db = new Database(); - const userSchema = new Schema({ + const userSchema = new Schema<{ + name: { + first: string; + last: string; + } + email: string; + age: number; + posts: string[]; + }>({ name: { first: String, last: String diff --git a/test/scripts/types/virtual.ts b/test/scripts/types/virtual.ts index 3f8f551..117aad2 100644 --- a/test/scripts/types/virtual.ts +++ b/test/scripts/types/virtual.ts @@ -3,7 +3,7 @@ const should = chai.should(); // eslint-disable-line import SchemaTypeVirtual from '../../../dist/types/virtual'; describe('SchemaTypeVirtual', () => { - const type = new SchemaTypeVirtual('test'); + const type = new SchemaTypeVirtual('test'); it('get()', () => { const getter = () => 'foo';