-
-
Notifications
You must be signed in to change notification settings - Fork 677
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
Inherited fields lost & types orphaned when implementing an interface #1425
Comments
I think that was fixed some time ago. Can you try on |
Interesting, I'll check it out! Where are you tracking these beta releases? There hasn't been a tag since 1.2.0-rc.1 |
@MichalLytek I tried again with the beta branch and got the same result: |
@russell-dot-js Sync version of build schema skips the schema check (which is async) thus may lead to generating invalid schema. If I change your example repository code into: async function main() {
await buildSchema({
resolvers: [QueryResolver],
emitSchemaFile: true,
});
}
main().catch(console.error); Then I get this error:
So if I fix your classes and decorators: @ObjectType({ implements: [SuperExample, Example] })
export class SuperDuperExample extends SuperExample { Then the generated schema file sounds looks correct:
The rules about interfaces are GraphQL spec rules. I just follow with the requirement of manually specifying all the interfaces in the inheritance chain. |
That's again a wrong schema design in your example repository. Remember that TypeGraphQL strip off all the not used types and interfaces. Basically, there's an auto include types implementing interface mechanism. So when you type this code: @InterfaceType()
export abstract class Example {
@Field(() => String)
id!: string;
}
@InterfaceType({ implements: Example })
export abstract class SuperExample extends Example {
@Field(() => String)
somethingElse!: string;
}
@ObjectType({ implements: SuperExample })
export class SuperSuperExample extends SuperExample {} TypeGraphQL does not see interface Example {
id: String!
}
type Query {
getExample: Example!
} So if you update your classes: @ObjectType({ implements: [SuperExample, Example] })
export class SuperSuperExample extends SuperExample {} It generates the schema as you wanted to 😄 interface Example {
id: String!
}
type Query {
getExample: Example!
}
interface SuperExample implements Example {
id: String!
somethingElse: String!
}
type SuperSuperExample implements Example & SuperExample {
id: String!
somethingElse: String!
} |
Thank you for the thorough response @MichalLytek - I especially appreciate you pointing out that that synchronous schema generation skips validation, I wasn't aware of that! I understand that the graphql spec specifies that all implemented interfaces must be specified, but this seems like something type-graphql should abstract out for us. Since we aren't writing graphql types directly, rather, we are essentially using OOP to define our types. In OOP, when C implements B, and B implements A, C implicitly implements A. Having to duplicate the knowledge of the entire inheritance chain not only leads to somewhat-spaghetti code, but also reduces or even eliminates the value of having interface B to begin with. Since we are writing classes to define our types, my intuition was that type-graphql would understand that:
should compile to:
We should have all of this knowledge at runtime while generating the schema - we know that C implements B and B implements A - so what is the advantage of forcing this nuance of graphql onto the developer? I understand that this is a graphql library, but if we wanted to write graphql schemas instead of typescript, we wouldn't be using type-graphql FYI this is particular painful when you have a large # of types related to a workflow - as the object moves through the workflow and its status changes, additional fields are added. This is where it bit me in particular, the maintenance of that code is a headache but only because the traditional rules of OOP are not followed |
You're absolutely right. I've created test snippets based on your example to make sure all works ok 💪 Closing as fixed by 84e7033 🔒 |
Describe the Bug
Hi @MichalLytek, great to see you contributing to the project again. Can't wait to get the next version!
To Reproduce
https://github.com/kingsmendv/type-graphql-issue-multi-level-interface
See the generated schema.gql
Expected Behavior
Logs
N/A
Environment (please complete the following information):
Additional Context
This is NOT the same as #726 or #907 but may be related to #373
One way to get the expected behavior is by duplicating the interface-inherits-interface definition on all your types. E.g. if you change
@ObjectType({ implements: SuperExample })
to@ObjectType({ implements: [Example, SuperExample] })
the schema will emit properly.The text was updated successfully, but these errors were encountered: