Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
alexneo2003 opened this issue Jan 15, 2023 · 2 comments
Open

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

alexneo2003 opened this issue Jan 15, 2023 · 2 comments

Comments

@alexneo2003
Copy link

alexneo2003 commented Jan 15, 2023

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?
@alexneo2003 alexneo2003 changed the title NestJS implementation Type 'Cat' is not assignable to type 'Document<any, any, any>' Jan 16, 2023
@alexneo2003
Copy link
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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants