feathersjs-ecosystem / feathers-mongoose

Easily create a Mongoose Service for Feathersjs.
MIT License
189 stars 96 forks source link

type definition error on MongooseServiceOptions<T & Document> #412

Closed gchokeen closed 2 years ago

gchokeen commented 2 years ago

https://github.com/feathersjs-ecosystem/feathers-mongoose/blob/0bda68806378dabc4c91b6a7005f72a2e49f5d19/types/index.d.ts#L25

I'm using feathers 4.5.11 and feathers-mongoose 8.4.0, on the fresh feathers generate application, I'm getting the bellow type error from feathers-mongoose package type definition


node_modules/feathers-mongoose/types/index.d.ts:25:35 - error TS2344: Type 'T & Document<any, any, any>' does not satisfy the constraint 'Document<any, any, any>'.
  The types of 'replaceOne(...).$where(...).and' are incompatible between these types.
    Type '(array: FilterQuery<T & Document<any, any, any>>[]) => Query<(T & Document<any, any, any>)[], T & Document<any, any, any>, {}, T & Document<...>>' is not assignable to type '(array: FilterQuery<Document<any, any, any>>[]) => Query<Document<any, any, any>[], Document<any, any, any>, {}, Document<any, any, any>>'.
      Types of parameters 'array' and 'array' are incompatible.
        Type 'FilterQuery<Document<any, any, any>>[]' is not assignable to type 'FilterQuery<T & Document<any, any, any>>[]'.
          Type 'FilterQuery<Document<any, any, any>>' is not assignable to type 'FilterQuery<T & Document<any, any, any>>'.
            Type 'FilterQuery<Document<any, any, any>>' is not assignable to type '{ [P in keyof (T & Document<any, any, any>)]?: (P extends "_id" ? [Extract<(T & Document<any, any, any>)[P], ObjectId>] extends [never] ? Condition<(T & Document<any, any, any>)[P]> : Condition<...> : [...] extends [...] ? Condition<...> : Condition<...>) | undefined; }'.

25   options: MongooseServiceOptions<T & Document>;

Whole package dependencies

 "dependencies": {
    "@feathersjs/authentication": "^4.5.11",
    "@feathersjs/authentication-local": "^4.5.11",
    "@feathersjs/authentication-oauth": "^4.5.11",
    "@feathersjs/configuration": "^4.5.11",
    "@feathersjs/errors": "^4.5.11",
    "@feathersjs/express": "^4.5.11",
    "@feathersjs/feathers": "^4.5.11",
    "@feathersjs/socketio": "^4.5.11",
    "@feathersjs/transport-commons": "^4.5.11",
    "compression": "^1.7.4",
    "cors": "^2.8.5",
    "feathers-hooks-common": "^5.0.6",
    "feathers-mongoose": "^8.4.0",
    "helmet": "^4.6.0",
    "mongodb-core": "^3.2.7",
    "mongoose": "^5.13.3",
    "serve-favicon": "^2.5.0",
    "winston": "^3.3.3"
  },
  "devDependencies": {
    "@types/compression": "^1.7.1",
    "@types/cors": "^2.8.12",
    "@types/helmet": "^4.0.0",
    "@types/jsonwebtoken": "^8.5.4",
    "@types/mocha": "^9.0.0",
    "@types/mongoose": "^5.11.97",
    "@types/serve-favicon": "^2.5.3",
    "@typescript-eslint/eslint-plugin": "^4.28.5",
    "@typescript-eslint/parser": "^4.28.5",
    "axios": "^0.21.1",
    "eslint": "^7.31.0",
    "mocha": "^8.4.0",
    "shx": "^0.3.3",
    "ts-mocha": "^8.0.0",
    "ts-node-dev": "^1.1.8",
    "typescript": "^4.3.5"
  }

Thanks Gowri

bartduisters commented 2 years ago

@gchokeen workaround, edit the file in node_modules:

  options: MongooseServiceOptions<Document<any, any, any>>;
daffl commented 2 years ago

This could be fixed with a pull request. You can edit the file here

daffl commented 2 years ago

Fixed in v8.4.1

clintonb commented 2 years ago

The changes in #413 where reverted by https://github.com/feathersjs-ecosystem/feathers-mongoose/pull/414/files#diff-093ad82a25aee498b11febf1cdcb6546e4d223ffcb49ed69cc275ac27ce0ccceL24-R24. This problem still occurs.

@daffl please reopen

daffl commented 2 years ago

These changes are backwards compatible as suggested by the linter. I was not able to reproduce the original error.

daffl commented 2 years ago

Apologies, I was looking at the wrong line of code. This should indeed be fixed.

bartduisters commented 2 years ago

Workaround, either do a manual edit of the file in node_modules.

  options: MongooseServiceOptions<Document<any, any, any>>;

Or, if you are like me, stuck on it being installed when deploying the code. Do this:

Add a directory called lib-types to the source of your project.

mkdir lib-types

Create a directory with the name of the library inside this new directory.

cd lib-types && mkdir feathers-mongoose

Create a file with the name index.d.ts inside this new directory.

cd feathers-mongoose && touch index.d.ts

Copy this content inside the file:

// TypeScript Version: 4.0
import { AdapterService, InternalServiceMethods, ServiceOptions } from '@feathersjs/adapter-commons';
import { Hook, Id, NullableId, Paginated, Params } from '@feathersjs/feathers';
import { Document, Model } from 'mongoose';

export namespace hooks {
    function toObject(options?: any, dataField?: string): Hook;
}

export namespace transactionManager {
    const beginTransaction: Hook;
    const commitTransaction: Hook;
    const rollbackTransaction: Hook;
}

export interface MongooseServiceOptions<T extends Document = any> extends ServiceOptions {
    Model: Model<T>;
    lean: boolean;
    overwrite: boolean;
    useEstimatedDocumentCount: boolean;
}

export class Service<T = any> extends AdapterService<T> implements InternalServiceMethods<T> {
  Model: Model<Document>;

  /*
  * This line has been manually changed for the workaround
  */
  options: MongooseServiceOptions<Document<any, any, any>>;

  constructor(config?: Partial<MongooseServiceOptions>);

  _find(params?: Params): Promise<T | T[] | Paginated<T>>;
  _get(id: Id, params?: Params): Promise<T>;
  _create(data: Partial<T> | Array<Partial<T>>, params?: Params): Promise<T | T[]>;
  _update(id: NullableId, data: T, params?: Params): Promise<T>;
  _patch(id: NullableId, data: Partial<T>, params?: Params): Promise<T>;
  _remove(id: NullableId, params?: Params): Promise<T>;
}

declare const mongoose: ((config?: Partial<MongooseServiceOptions>) => Service);
export default mongoose;

In your tsconfig.json, add the lib-types directory to the paths property.

{
  "compilerOptions": {
    "target": "es2018",
    "module": "commonjs",
    "outDir": "./lib",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "paths": {
      "*": ["./*", "./lib-types/*"]
    }
  },
  "exclude": ["test"]
}
daffl commented 2 years ago

Ok, this should be actually fixed in v8.4.2. Thank you for the PR @bartduisters!