Reputation: 95
I am trying to use a context to define the type for the entity manage 'em' but the em type returns an error: type 'IDatabaseDriver' does not satisfy the constraint 'AbstractSqlDriver'. Type 'IDatabaseDriver' is missing the following properties from type 'AbstractSqlDriver': connection, replicas, platform, mapJoinedProps, and 24 more.
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
}
}
Console Error
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>>
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Upvotes: 0
Views: 1596
Reputation: 18389
You should use the EntityManager
expoted from driver package. That way it will be correctly typed to SqlEntityManager<PostgreSqlDriver>
:
import { EntityManager } from "@mikro-orm/postgresql";
export type MyContext = {
em: EntityManager
}
And then when you initialze the ORM, you should specify the driver type:
const orm = await MikroORM.init<PostgreSqlDriver>(microConfig)
Then the orm.em
is correctly typed the same way, so to SqlEntityManager<PostgreSqlDriver>
.
Also instead of Parameters<typeof MikroORM.init>[0]
you can use just Options
(exported from the core package).
Upvotes: 1