类型 'IDatabaseDriver<Connection>' 不满足约束 'AbstractSqlDriver<AbstractSqlConnection>'

时间:2021-01-10 16:34:14

标签: node.js typescript postgresql express mikro-orm

我正在尝试使用上下文来定义实体管理“em”的类型,但 em 类型返回错误:类型“IDatabaseDriver”不满足约束“AbstractSqlDriver”。 “IDatabaseDriver”类型缺少“AbstractSqlDriver”类型中的以下属性:连接、副本、平台、mapJoinedProps 等。

types.ts

import { Connection } from "@mikro-orm/core";
import { IDatabaseDriver } from "@mikro-orm/core/drivers/IDatabaseDriver";
import { EntityManager } from "@mikro-orm/postgresql";

export type MyContext = {
    em:  EntityManager<any> & EntityManager<IDatabaseDriver<Connection>>
}

mikro-orm.config.ts

import { __PROD__ } from "./constants";
import { Post } from "./entities/Post";
import { MikroORM } from '@mikro-orm/core'
import {PostgreSqlDriver} from '@mikro-orm/postgresql'
import { User } from "./entities/User";
export default {
    migrations:{
        path: process.cwd() + '/src/migrations', // path to folder with migration files
        pattern: /^[\w-]+\d+\.[tj]s$/, // how to match migration files
        disableForeignKeys: false
    },
    driver: PostgreSqlDriver,
    driverOptions: { connection: { timezone: '00:00' } },
    entities: [Post,User ],
    dbName:'altevibes',
    user:'logorcehab',
    password: 'login@Logout64',
    type:'postgresql',
    debug: !__PROD__
} as Parameters<typeof MikroORM.init>[0];

index.ts

import {MikroORM } from "@mikro-orm/core"
import 'reflect-metadata'
import {__PROD__} from "./constants"
//import { Post } from "./entities/Post"
import express from 'express'
import microConfig from './mikro-orm.config'
import { ApolloServer } from 'apollo-server-express'
import { buildSchema } from 'type-graphql'
import { PostsResolver } from "./resolvers/posts"
import { UserResolver } from "./resolvers/user"
const main = async () => {
  const orm = await MikroORM.init(microConfig)
  await orm.getMigrator().up()
  
  const app= express()
  
  const apolloSever = new ApolloServer({
    schema: await buildSchema({
      resolvers: [PostsResolver, UserResolver],
      validate: false
    }),
    context: () => ({ em: orm.em })
  })
  apolloSever.applyMiddleware({ app })
  app.listen(8000,()=>{
      console.log('server on localhost 8000')
  })
}

console.log("Hello World")

main().catch((e)=>{console.log(e)});

posts.ts

import { Resolver,Query, Ctx,Arg, Int, Mutation } from 'type-graphql'
import { Post } from '../entities/Post'
import { MyContext } from '../types'
@Resolver()
export class PostsResolver {
    @Query(()=>[Post])
    posts( @Ctx() {em}: MyContext ): Promise<Post[]> {
        return em.find(Post, {})
    }
    @Query(()=>Post,{nullable : true})
    post(
        @Arg('id', () => Int) id: number,  
        @Ctx() {em}: MyContext )
        : Promise<Post | null> {
        return em.findOne(Post, { id })
    }
    @Mutation(()=>Post)
    async createPost(
        @Arg('title', () => String) title: string,  
        @Ctx() {em}: MyContext )
        : Promise<Post> {
        const post = em.create(Post, {title})
        await em.persistAndFlush(post)
        return post
    }
    @Mutation(()=>Post,{ nullable: true})
    async updatePost(
        @Arg('id') id: number,
        @Arg('title',()=> String,{ nullable: true }) title: string, 
        @Ctx() {em}: MyContext )
        : Promise<Post | null> {
        const post = await em.findOne(Post, { id })
        if (!post) {
            return null
        }
        if (typeof title === 'undefined'){
            return null
        }
        post.title = title
        await em.persistAndFlush(post)        
        return post       
    }
    @Mutation(()=>Boolean)
    async deletePost(
        @Arg('id', () => Int) id: number,  
        @Ctx() {em}: MyContext )
        : Promise<Boolean> {
            try {
                await em.nativeDelete(Post, { id })
            } catch (error) {
                return false
            }
        return true
    }
}

user.ts

import { User } from '../entities/User'
import { Resolver, Ctx,Arg, Mutation, InputType, Field } from 'type-graphql'
import argon2 from 'argon2'
import { MyContext } from '../types'
@InputType()
class UsernamePasswordInput {
    @Field()
    username: string

    @Field()
    password: string
}

@Resolver()
export class UserResolver {
    @Mutation(()=> String)
    async register(
        @Arg("options") options: UsernamePasswordInput,
        @Ctx() { em }: MyContext
    ){
        const hashedPassword = argon2.hash(options.password)
        const user = em.create(User, { username: options.username, password: hashedPassword })
        await em.persistAndFlush(user)
        return user
    }
    
}

控制台错误


src/resolvers/posts.ts:6:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.

6     @Query(()=>[Post])
      ~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:6:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.
  Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'void | TypedPropertyDescriptor<({ em }: MyContext) => Promise<Post[]>>'.
    Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'TypedPropertyDescriptor<({ em }: MyContext) => Promise<Post[]>>'.
      Types of property 'value' are incompatible.
        Type 'unknown' is not assignable to type '(({ em }: MyContext) => Promise<Post[]>) | undefined'.
          Type 'unknown' is not assignable to type '({ em }: MyContext) => Promise<Post[]>'.

6     @Query(()=>[Post])
      ~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:10:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.

10     @Query(()=>Post,{nullable : true})
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:10:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.
  Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'void | TypedPropertyDescriptor<(id: number, { em }: MyContext) => Promise<Post | null>>'.
    Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'TypedPropertyDescriptor<(id: number, { em }: MyContext) => Promise<Post | null>>'.
      Types of property 'value' are incompatible.
        Type 'unknown' is not assignable to type '((id: number, { em }: MyContext) => Promise<Post | null>) | undefined'.
          Type 'unknown' is not assignable to type '(id: number, { em }: MyContext) => Promise<Post | null>'.

10     @Query(()=>Post,{nullable : true})
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:17:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.

17     @Mutation(()=>Post)
       ~~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:17:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.
  Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'void | TypedPropertyDescriptor<(title: string, { em }: MyContext) => Promise<Post>>'.
    Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'TypedPropertyDescriptor<(title: string, { em }: MyContext) => Promise<Post>>'.
      Types of property 'value' are incompatible.
        Type 'unknown' is not assignable to type '((title: string, { em }: MyContext) => Promise<Post>) | undefined'.
          Type 'unknown' is not assignable to type '(title: string, { em }: MyContext) => Promise<Post>'.

17     @Mutation(()=>Post)
       ~~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:26:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.

26     @Mutation(()=>Post,{ nullable: true})
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:26:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.
  Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'void | TypedPropertyDescriptor<(id: number, title: string, { em }: MyContext) => Promise<Post | null>>'.
    Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'TypedPropertyDescriptor<(id: number, title: string, { em }: MyContext) => Promise<Post | null>>'.
      Types of property 'value' are incompatible.
        Type 'unknown' is not assignable to type '((id: number, title: string, { em }: MyContext) => Promise<Post | null>) | undefined'.
          Type 'unknown' is not assignable to type '(id: number, title: string, { em }: MyContext) => Promise<Post | null>'.

26     @Mutation(()=>Post,{ nullable: true})
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:43:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.

43     @Mutation(()=>Boolean)
       ~~~~~~~~~~~~~~~~~~~~~~

src/resolvers/posts.ts:43:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.
  Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'void | TypedPropertyDescriptor<(id: number, { em }: MyContext) => Promise<Boolean>>'.
    Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'TypedPropertyDescriptor<(id: number, { em }: MyContext) => Promise<Boolean>>'.
      Types of property 'value' are incompatible.
        Type 'unknown' is not assignable to type '((id: number, { em }: MyContext) => Promise<Boolean>) | undefined'.
          Type 'unknown' is not assignable to type '(id: number, { em }: MyContext) => Promise<Boolean>'.

43     @Mutation(()=>Boolean)
       ~~~~~~~~~~~~~~~~~~~~~~

src/resolvers/user.ts:16:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.

16     @Mutation(()=> String)
       ~~~~~~~~~~~~~~~~~~~~~~

src/resolvers/user.ts:16:5 - error TS1241: Unable to resolve signature of method decorator when called as an expression.
  Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'void | TypedPropertyDescriptor<(options: UsernamePasswordInput, { em }: MyContext) => Promise<User>>'.
    Type 'TypedPropertyDescriptor<unknown>' is not assignable to type 'TypedPropertyDescriptor<(options: UsernamePasswordInput, { em }: MyContext) => Promise<User>>'.
      Types of property 'value' are incompatible.
        Type 'unknown' is not assignable to type '((options: UsernamePasswordInput, { em }: MyContext) => Promise<User>) | undefined'.
          Type 'unknown' is not assignable to type '(options: UsernamePasswordInput, { em }: MyContext) => Promise<User>'.

16     @Mutation(()=> String)
       ~~~~~~~~~~~~~~~~~~~~~~

src/types.ts:6:45 - error TS2344: Type 'IDatabaseDriver<Connection>' does not satisfy the constraint 'AbstractSqlDriver<AbstractSqlConnection>'.
  Type 'IDatabaseDriver<Connection>' is missing the following properties from type 'AbstractSqlDriver<AbstractSqlConnection>': connection, replicas, platform, mapJoinedProps, and 24 more.

6     em:  EntityManager<any> & EntityManager<IDatabaseDriver<Connection>>
                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~

1 个答案:

答案 0 :(得分:1)

您应该使用从驱动程序包中导出的 EntityManager。这样它就会被正确地输入到 SqlEntityManager<PostgreSqlDriver>:

import { EntityManager } from "@mikro-orm/postgresql";

export type MyContext = {
    em:  EntityManager
}

然后当你初始化 ORM 时,你应该指定驱动程序类型:

const orm = await MikroORM.init<PostgreSqlDriver>(microConfig)

然后 orm.em 以相同的方式正确键入,因此为 SqlEntityManager<PostgreSqlDriver>

您也可以只使用 Parameters<typeof MikroORM.init>[0](从核心包导出)来代替 Options

相关问题