MichalLytek / type-graphql

Create GraphQL schema and resolvers with TypeScript, using classes and decorators!

Home Page:https://typegraphql.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Deno support

MichalLytek opened this issue · comments

It might be worth considering, as now Deno should have better interoperability with npm.
https://deno.com/blog/v1.31

Maybe examples are enough, maybe we need to abstract some things and release proper package on deno land 👀

would definitely love having deno support!

As far as I can see, an example should be enough.
Can anyone with Deno experience build a simple example?

@carlocorradini it feels like the biggest issue might be with the reflection usage and tsconfig options. I'll try to put a demo together and see how it goes.

Ok, looks like it's almost there just by using the npm specifier for imports. For the unpatient:

// main.ts
import "npm:reflect-metadata";
import { graphql } from "npm:graphql@16.8.1";  
import { buildSchema, /* ... */ } from "npm:type-graphql@2.0.0-beta.3";

// everything works out of the box like in the examples

And compiler options in deno.json:

{
  "compilerOptions": {
    "strictPropertyInitialization": false,
    "emitDecoratorMetadata": true
  },
}

Note that decorators come by default with Deno. Also, I'm personally not a big fan of strictPropertyInitialization. It's only there to allow defining various object types, like:

@InputType()
class NewRecipeInput {
  @Field()
  title: string;
}

Without the option, TS would (rightfully) complain that title is optional, since it has no initializer. An alternative to disabling this check in the full codebase would be to assert only for places where these are defined, ie:

@InputType()
class NewRecipeInput {
  @Field()
  title!: string; // added the ! operator
}

I haven't tested older versions, but I think someone taking on Deno as a runtime would probably prefer jumping on the type-graphql 2.0 train. I had a bit of trouble here using the latest beta version. The release documents graphql 16.7.1 as a peer dependency but it actually only works with 16.8.1 from what I can see.


I have a GraphQL project with Deno where I'd like to use type-graphql. Depending on availability I could try to contribute to docs and come back to this thread if I hit any roadblocks for the more complex functionality.

Ok, looks like it's almost there just by using the npm specifier for imports. For the unpatient:

// main.ts
import "npm:reflect-metadata";
import { graphql } from "npm:graphql@16.8.1";  
import { buildSchema, /* ... */ } from "npm:type-graphql@2.0.0-beta.3";

// everything works out of the box like in the examples

And compiler options in deno.json:

{
  "compilerOptions": {
    "strictPropertyInitialization": false,
    "emitDecoratorMetadata": true
  },
}

Note that decorators come by default with Deno. Also, I'm personally not a big fan of strictPropertyInitialization. It's only there to allow defining various object types, like:

@InputType()
class NewRecipeInput {
  @Field()
  title: string;
}

Without the option, TS would (rightfully) complain that title is optional, since it has no initializer. An alternative to disabling this check in the full codebase would be to assert only for places where these are defined, ie:

@InputType()
class NewRecipeInput {
  @Field()
  title!: string; // added the ! operator
}

I haven't tested older versions, but I think someone taking on Deno as a runtime would probably prefer jumping on the type-graphql 2.0 train. I had a bit of trouble here using the latest beta version. The release documents graphql 16.7.1 as a peer dependency but it actually only works with 16.8.1 from what I can see.

I have a GraphQL project with Deno where I'd like to use type-graphql. Depending on availability I could try to contribute to docs and come back to this thread if I hit any roadblocks for the more complex functionality.

Hi @ClaudiuCeia, thanks for the example, however seems it is not working properly, I'm trying to use @Args and @Arg decorators in supabase edge functions without get it works. I guess it is related to the new way to handle decorators in Typescript 5 but I'm not sure.

I get this error

error: Uncaught (in promise) Error: Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for parameter #0 of 'programs' of 'ProgramsResolver' class.
    at findType (file:///Users/eduardo/Library/Caches/deno/npm/registry.npmjs.org/type-graphql/2.0.0-beta.3/build/esm/helpers/findType.js:22:15)
    at getParamInfo (file:///Users/eduardo/Library/Caches/deno/npm/registry.npmjs.org/type-graphql/2.0.0-beta.3/build/esm/helpers/params.js:7:38)
    at file:///Users/eduardo/Library/Caches/deno/npm/registry.npmjs.org/type-graphql/2.0.0-beta.3/build/esm/decorators/Args.js:9:16
    at file:///Users/eduardo/Code/jules/rebates/supabase/functions/graphql/resolvers/programs.resolver.ts:9:5
    at DecorateProperty (file:///Users/eduardo/Library/Caches/deno/npm/registry.npmjs.org/reflect-metadata/0.2.1/Reflect.js:561:33)
    at Reflect.decorate (file:///Users/eduardo/Library/Caches/deno/npm/registry.npmjs.org/reflect-metadata/0.2.1/Reflect.js:136:24)
    at _ts_decorate (file:///Users/eduardo/Code/jules/rebates/supabase/functions/graphql/resolvers/programs.resolver.ts:3:90)
    at file:///Users/eduardo/Code/jules/rebates/supabase/functions/graphql/resolvers/programs.resolver.ts:17:1

using this deno version

❯ deno --version
deno 1.39.1 (release, x86_64-apple-darwin)
v8 12.0.267.8
typescript 5.3.3

Seems for now is not usable

@esalazarv the actual code snippet would help. I'm thinking you're running into a limitation of TS reflection rather than Deno runtime, which is documented in the docs:

For simple types (like string or boolean) this is all that's needed but due to a limitation in TypeScript's reflection, we need to provide info about generic types (like Array or Promise). So to declare the Rate[] type, we have to use the explicit [ ] syntax for array types - @field(type => [Rate]). For nested arrays, we just use the explicit [ ] notation to determine the depth of the array, e.g. @field(type => [[Int]]) would tell the compiler we expect an integer array of depth 2.

Either way, you should be able to fix it by specifying the return type in the decorator, ie:

@Arg("name", () => String)  

@esalazarv the actual code snippet would help. I'm thinking you're running into a limitation of TS reflection rather than Deno runtime, which is documented in the docs:

For simple types (like string or boolean) this is all that's needed but due to a limitation in TypeScript's reflection, we need to provide info about generic types (like Array or Promise). So to declare the Rate[] type, we have to use the explicit [ ] syntax for array types - @field(type => [Rate]). For nested arrays, we just use the explicit [ ] notation to determine the depth of the array, e.g. @field(type => [[Int]]) would tell the compiler we expect an integer array of depth 2.

Either way, you should be able to fix it by specifying the return type in the decorator, ie:

@Arg("name", () => String)  

@ClaudiuCeia Thanks for your help, I just tested and it works like a charm.