Type-graphql: Feature: Decorate classes without @Decorators.

Created on 28 Mar 2019  路  5Comments  路  Source: MichalLytek/type-graphql

If I have existing models that are used in other apps not requiring type-graphql or graphql at all, it'd be nice to be able to decorate those without wrapping them.

Lets say I have:

/** @org/db/Doc.ts */
interface Doc {
    _id: ObjectId;
    createdAt: Date;
    updatedAt: Date;
}

abstract class Document<T extends Doc> {
    public doc: T;

    constructor(doc: T) {
        this.doc = doc;
    }

    get id(): string {
        return this.doc._id.toHexString();
    }

    // ...
}

/** @org/db/User.ts */
interface UserDocument extends Doc {
    name: string;
}

class User extends Document<UserDocument> {
    get name(): string {
        return this.doc.name;
    }
}

/** @other/graphql/___.ts */
import { ObjectTypeDecorator } from 'type-graphql';
import { User, Document } from '@org/db';

const documentDecorator = new ObjectTypeDecorator(Document);
documentDecorator.field('id');
documentDecorator.field('createdAt');
documentDecorator.field('updatedAt');

const userDecorator = new ObjectTypeDecorator(User);
userDecorator.field('name');

// can now use "User" as a type throughout.
Community Discussion Enhancement

Most helpful comment

@j
You can call the decorators manually, like in transpiled code:

class User {
  name: string;
};

ObjectType(options)(User);
Field({ nullable: true })(User.prototype, "name");

I don't want to expose utils like ObjectTypeDecorator as it's against TypeGraphQL goal to define classes with decorators to produce GraphQL schema.

In my production apps I just use the shim and the decorators on unrelated classes like RegisterFormState 馃槃 I can share the form state, input type shape and typeorm entity at once 馃槈

All 5 comments

Interfaces doesn't exist at runtime, so we have absolutely no type metadata available 馃槥
Also in comments you can't use runtime values, so it's all string based with no type safety.

Maybe you should write your code generator that will convert the interfaces to classes with decorators? 馃

Or just use the decorators and type-graphql shim?
https://typegraphql.ml/docs/browser-usage.html

The above code example are classes backed by interfaces. I want to use type-graphql on existing classes without having to wrap them to setup fields, etc.

@j
You can call the decorators manually, like in transpiled code:

class User {
  name: string;
};

ObjectType(options)(User);
Field({ nullable: true })(User.prototype, "name");

I don't want to expose utils like ObjectTypeDecorator as it's against TypeGraphQL goal to define classes with decorators to produce GraphQL schema.

In my production apps I just use the shim and the decorators on unrelated classes like RegisterFormState 馃槃 I can share the form state, input type shape and typeorm entity at once 馃槈

Mobx has an interesting approach, https://mobx.js.org/best/decorators.html. Maybe that approach would work for you?

@cramhead that's pretty dang cool. It's sort of what I was thinking originally.

I've since moved my models to my graph layer and with apollo federation coming soon, will be moving every model to it's specific service. Originally we had models and repositories in their own package and I wanted that library to be unaware of type-graphql and to just decorate the classes after the fact. I ended up not doing this though, but the Mobx approach looks pretty cool.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MichalLytek picture MichalLytek  路  3Comments

robertchung97 picture robertchung97  路  3Comments

laukaichung picture laukaichung  路  3Comments

MichalLytek picture MichalLytek  路  4Comments

avkonst picture avkonst  路  3Comments