Skip to content

Type 'Cat' is not assignable to type 'Document<any, any, any>' #424

Open
@alexneo2003

Description

@alexneo2003

Latest version installed
package.json

    "@nestjs/apollo": "^10.1.7",
    "@nestjs/common": "^9.0.0",
    "@nestjs/core": "^9.0.0",
    "@nestjs/graphql": "^10.1.7",
    "@nestjs/mongoose": "^9.2.1",
    "@nestjs/platform-express": "^9.0.0",
    "apollo-server-express": "^3.11.1",
    "graphql": "^16.6.0",
    "graphql-compose": "9.0.10",
    "graphql-compose-mongoose": "9.7.2",
    "mongoose": "6.8.3",

Following instructions and try using graphql-compose-mongoose in NestJS project

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { schemaComposer } from 'graphql-compose';
import { composeMongoose } from 'graphql-compose-mongoose';
import mongoose from 'mongoose';

@Schema({ timestamps: true })
@ObjectType()
export class Cat {
  @Prop()
  @Field(() => String)
  name: string;

  @Prop()
  @Field(() => Int)
  age: number;

  @Prop()
  @Field(() => String)
  breed: string;
}

const schema = SchemaFactory.createForClass(Cat);

const CatModel = mongoose.model('Cat', schema);
const CatTC = composeMongoose(CatModel, {});

schemaComposer.Query.addFields({
  catById: CatTC.mongooseResolvers.findById(),
});

export const CatSchema = schemaComposer.buildSchema();

But got error at const CatTC = composeMongoose(CatModel, {});

Argument of type 'Model<Cat, {}, {}, {}, Schema<Cat, Model<Cat, any, any, any, any>, {}, {}, {}, {}, DefaultSchemaOptions, Cat>>' is not assignable to parameter of type 'Model<Document<any, any, any>, {}, {}, {}, any>'.
  The types returned by 'castObject(...)' are incompatible between these types.
    Type 'Cat' is not assignable to type 'Document<any, any, any>'.ts(2345)

I can pass any generic const CatModel = mongoose.model<any>('Cat', schema); but still having problem
NestJS saying

[Nest] 11348  - 15.01.2023, 20:05:21   ERROR [ExceptionHandler] The 2nd parameter to `mongoose.model()` should be a schema or a POJO
Error: The 2nd parameter to `mongoose.model()` should be a schema or a POJO

Schema injected in nestjs at module file

cat.module.ts

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { Cat, CatSchema } from './cat.model';
import { CatService } from './cat.service';
import { CatResolver } from './cat.resolver';

@Module({
  imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
  providers: [CatService, CatResolver],
})
export class CatModule {}

Another way - cloning example and seen you using any heneric too export const Category = model<any>('Category', CategorySchema);
If i remove it i got error

Argument of type 'Model<unknown, {}, {}>' is not assignable to parameter of type 'Model<Document<any, any, any>, {}, {}>'.
  Types of property 'find' are incompatible.
    Type '{ (callback?: Callback<(Document<any, any, unknown> & { _id: unknown; })[]>): Query<(Document<any, any, unknown> & { _id: unknown; })[], Document<any, any, unknown> & { _id: unknown; }, {}, unknown>; (filter: FilterQuery<...>, callback?: Callback<...>): Query<...>; (filter: FilterQuery<...>, projection?: any, option...' is not assignable to type '{ (callback?: Callback<(Document<any, any, any> & { _id: any; })[]>): Query<(Document<any, any, any> & { _id: any; })[], Document<any, any, any> & { ...; }, {}, Document<...>>; (filter: FilterQuery<...>, callback?: Callback<...>): Query<...>; (filter: FilterQuery<...>, projection?: any, options?: QueryOptions, callb...'.
      Types of parameters 'callback' and 'callback' are incompatible.
        Types of parameters 'result' and 'result' are incompatible.
          Type 'unknown[]' is not assignable to type 'Document<any, any, any>[]'.
            Type 'unknown' is not assignable to type 'Document<any, any, any>'.ts(2345)

If update packages to latest version - got same error as in my own project

Based on the above, there are two questions:

  1. How using package without generic?
  2. How integrate with NestJS?

Activity

changed the title [-]NestJS implementation[/-] [+]Type 'Cat' is not assignable to type 'Document<any, any, any>'[/+] on Jan 16, 2023
alexneo2003

alexneo2003 commented on Jan 20, 2023

@alexneo2003
Author

I found ansver on my 2 question
compose schema

export const UserSchema = SchemaFactory.createForClass(User);

const UserModel = mongoose.model<any>('User', UserSchema);
const UserTC = composeMongoose(UserModel, {});

schemaComposer.Query.addFields({
  userById: UserTC.mongooseResolvers.findById(),
  getUser: UserTC.mongooseResolvers.findOne(),
  getAllUsers: UserTC.mongooseResolvers.findMany(),
});

schemaComposer.Mutation.addFields({
  updateUser: UserTC.mongooseResolvers.updateOne(),
  removeUser: UserTC.mongooseResolvers.removeOne(),
});

const composeSchema = schemaComposer.buildSchema();

writeFileSync(join(process.cwd(), `/src/gql-schema/${User.name}.graphql`), printSchema(composeSchema));

connect compose schemas files to NestJS server

@Module({
  imports: [
    MongooseModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: async (configService: ConfigService) => ({
        uri: process.env.MONGO_URI || configService.get('MONGO_URI'),
        useNewUrlParser: true,
        useUnifiedTopology: true,
      }),
      inject: [ConfigService],
    }),
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
-     autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
+     typePaths: ['./**/*.graphql'],
    }),
    UserModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

but i steel have first question

tatejones

tatejones commented on Nov 8, 2023

@tatejones

Did you get any resolution for your first question?

graphql-compose-mongoose : 9.8.0
mongoose: 7.6.4

The basic code from the site fails TS.

import { composeMongoose } from "graphql-compose-mongoose"
import mongoose from "mongoose"

const LanguagesSchema = new mongoose.Schema({
    language: String,
    skill: {
        type: String,
        enum: ["basic", "fluent", "native"],
    },
})

const UserSchema = new mongoose.Schema({
    name: String, // standard types
    age: {
        type: Number,
        index: true,
    },
    ln: {
        type: [LanguagesSchema], // you may include other schemas (here included as array of embedded documents)
        default: [],
        alias: "languages", // in schema `ln` will be named as `languages`
    },
    contacts: {
        // another mongoose way for providing embedded documents
        email: String,
        phones: [String], // array of strings
    },
    gender: {
        // enum field with values
        type: String,
        enum: ["male", "female"],
    },
    someMixed: {
        type: mongoose.Schema.Types.Mixed,
        description: "Can be any mixed type, that will be treated as JSON GraphQL Scalar Type",
    },
})
const User = mongoose.model("User", UserSchema)

const customizationOptions = {} // left it empty for simplicity, described below
const UserTC = composeMongoose(**User**, customizationOptions) <=====

Argument of type 'Model<{ ln: DocumentArray<{ language?: string | undefined; skill?: "basic" | "fluent" | "native" | undefined; }>; name?: string | undefined; age?: number | undefined; contacts?: { ...; } | undefined; gender?: "male" | ... 1 more ... | undefined; someMixed?: any; }, ... 4 more ..., Schema<...>>' is not assignable to parameter of type 'Model<Document<any, any, any>, {}, {}, {}, Document<unknown, {}, Document<any, any, any>> & Document<any, any, any> & { _id: ObjectId; }, any>'.
The types returned by 'castObject(...)' are incompatible between these types.
Type '{ ln: DocumentArray<{ language?: string | undefined; skill?: "basic" | "fluent" | "native" | undefined; }>; name?: string | undefined; age?: number | undefined; contacts?: { ...; } | undefined; gender?: "male" | ... 1 more ... | undefined; someMixed?: any; }' is not assignable to type 'Document<any, any, any>'.ts(2345)

image

sylv1b

sylv1b commented on May 21, 2025

@sylv1b

I did it like this, works like a charm:

import mongoose from "mongoose";

export const UserSchema = new mongoose.Schema({
  name: String, // standard types
  age: {
    type: Number,
    index: true,
  },
  contacts: {
    // another mongoose way for providing embedded documents
    email: String,
    phones: [String], // array of strings
  },
  gender: {
    // enum field with values
    type: String,
    enum: ["male", "female"],
  },
  someMixed: {
    type: mongoose.Schema.Types.Mixed,
    description:
      "Can be any mixed type, that will be treated as JSON GraphQL Scalar Type",
  },
});

export interface UserSchemaType extends mongoose.Document {
  name: string;
  age: number;
  contacts: {
    email: string;
    phones: string[];
  };
  gender: string;
  someMixed: any;
}
export const User = mongoose.model<UserSchemaType>("User", UserSchema);

const customizationOptions = {}; // optional
export const UserTC = composeMongoose(User, customizationOptions);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @tatejones@alexneo2003@sylv1b

        Issue actions

          Type 'Cat' is not assignable to type 'Document<any, any, any>' · Issue #424 · graphql-compose/graphql-compose-mongoose