Search code examples
javascriptnode.jstypescriptnestjstypeorm

Sudden TypeORM FindConditions type errors


After reinstalling node_modules I am suddenly getting a FindOneOptions/ObjectID error in my NestJS service.

Was building fine minutes ago beforehand. Makes me wonder, is this a code err or a typings err?

Using "@nestjs/typeorm": "^7.1.5"
Which seems to be using typeorm 0.2.35:
Local installed version: 0.2.35.
Global installed TypeORM version: 0.2.37.

The actual code

async getOne(id: number, userId?: string, type?: XPType, currentUser?: User) {
    const options: FindConditions<XP> = {
        id
    };
    userId && (options.userId = userId);
    type && (options.type = type);

    const post = await XP.findOne(options); // <-- error
    ...

Here is the actual error:

No overload matches this call.
  Overload 1 of 3, '(this: ObjectType<XP>, id?: string | number | Date | ObjectID, options?: FindOneOptions<XP>): Promise<...>', gave the following error.
    Argument of type 'FindConditions<XP>' is not assignable to parameter of type 'string | number | Date | ObjectID'.
      Type 'FindConditions<XP>' is missing the following properties from type 'ObjectID': generationTime, equals, generate, getTimestamp, toHexString
  Overload 2 of 3, '(this: ObjectType<XP>, options?: FindOneOptions<XP>): Promise<XP>', gave the following error.
    Type 'FindConditions<XP>' has no properties in common with type 'FindOneOptions<XP>'.
  Overload 3 of 3, '(this: ObjectType<XP>, conditions?: FindConditions<XP>, options?: FindOneOptions<XP>): Promise<...>', gave the following error.
    Argument of type 'import("/Users/bracicot/dev/dev-server/dev-server/node_modules/typeorm/find-options/FindConditions").FindConditions<import("/Users/bracicot/dev/dev-server/packages/server-common/dist/entities/experience-post.entity").XP>' is not assignable to parameter of type 'import("/Users/bracicot/dev/dev-server/packages/server-common/node_modules/typeorm/find-options/FindConditions").FindConditions<import("/Users/bracicot/dev/dev-server/packages/server-common/dist/entities/experience-post.entity").XP>'.
      Types of property 'userId' are incompatible.
        Type 'string | import("/Users/bracicot/dev/dev-server/dev-server/node_modules/typeorm/find-options/FindOperator").FindOperator<string>' is not assignable to type 'string | import("/Users/bracicot/dev/dev-server/packages/server-common/node_modules/typeorm/find-options/FindOperator").FindOperator<string>'.
          Type 'FindOperator<string>' is not assignable to type 'string | FindOperator<string>'.
            Type 'import("/Users/bracicot/dev/dev-server/dev-server/node_modules/typeorm/find-options/FindOperator").FindOperator<string>' is not assignable to type 'import("/Users/bracicot/dev/dev-server/packages/server-common/node_modules/typeorm/find-options/FindOperator").FindOperator<string>'.
              Types have separate declarations of a private property '_type'.ts(2769)
const options: FindConditions<XP>

Seems to be related to 4241 but am not sure. I'm hoping someone can help me understand this.


Solution

  • From the error:

    1. Overload 3 is the one you're attempting, and the one that SHOULD resolve, because it's the only one which includes the FindConditions parameter: (this: ObjectType<XP>, conditions?: FindConditions<XP>, options?: FindOneOptions<XP>): Promise<...>

    2. Digging further, there is a discrepancy between the following:

      'string | import("/Users/bracicot/dev/dev-server/dev-server/node_modules/typeorm/find-options/FindOperator").FindOperator<string>'
      

      is not assignable to type

      'string | import("/Users/bracicot/dev/dev-server/packages/server-common/node_modules/typeorm/find-options/FindOperator").FindOperator<string>
      

      It looks like you have two packages:

      1. dev-server
      2. server-common

      and that these are including SEPARATE node_modules/typeorm/find-options/FindOperator instances, forcing your compiler to regard them as different types. This is backed up by the last error statement; Types have separate declarations of a private property '_type'..

    3. Conclusively, I think you should consolidate the node_modules used. There are several ways to do this and I won't suggest which to take, because I think it depends on variables unknown to me. The main two approaches that spring to my mind however are

      1. Using a monorepo tool (I got relevant hits duck-duck-go-ing "monorepo tools") and/or package manager (pnpm, npm/yarn in workspace mode) which solves this systematically for you
      2. Have server-common (which sounds like a supporting library) either be the sole includer of the dependencies (specifically, typeorm), or have them be listed as peer-dependencies so that the application including server-common gets the say on what types it uses.

      Edit:

      1. After a re-read, I also realised that the error occurred After reinstalling node_modules, so it's possible that a third option would be to simply ensure a consistent version of typeorm by strictly specifying the dependency without ^, ~, or x notations using the exact same version in every relevant package.json file.