Skip to content
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

'createUnionType' ignores extends #587

Closed
WimSuenensDIRACIndustries opened this issue Mar 28, 2020 · 3 comments
Closed

'createUnionType' ignores extends #587

WimSuenensDIRACIndustries opened this issue Mar 28, 2020 · 3 comments
Labels
Bug 🐛 Something isn't working Community 👨‍👧 Something initiated by a community Solved ✔️ The issue has been solved
Milestone

Comments

@WimSuenensDIRACIndustries

When you use 'extends' on the ObjectType, createUnionType only resolves to the base ObjectType and ignores the extended objects.
This also applies, when you wouldn't use 'extends', but define the properties on the other objects. As soon as the new object defines the same properties (+ some additional), it is ignored in the UnionType.

import { ObjectType, Field, createUnionType } from "type-graphql";
import { User } from "../../database/postgresql/models/User";

@ObjectType()
export class SuccessMessage {
    @Field()
    success: boolean;

    @Field()
    message: string;
}

@ObjectType()
export class SuccessMessage_Token extends SuccessMessage {
    @Field()
    accessToken: string;

    @Field()
    user: User;
}

@ObjectType()
export class ErrorMessage extends SuccessMessage{
    @Field()
    success: boolean;

    @Field()
    error: string;
}

export const ResponseMessageUnion = createUnionType({
    name: "ResponseMessage", // the name of the GraphQL union
    types: () => [
            SuccessMessage,
            SuccessMessage_Token,
            ErrorMessage
        ], // function that returns array of object types classes
    resolveType: value => {
        if ("error" in value) {
            return ErrorMessage;
        }
        if ("accessToken" in value) {
            return SuccessMessage_Token
        }
        if ("error" !in value && "accessToken" !in value) {
            return SuccessMessage;
        }
        return undefined;
    }
});

In this case, it's only possible the resolve to 'SuccessMessage'

(alias) createUnionType<(typeof SuccessMessage)[]>(config: UnionTypeConfig<(typeof SuccessMessage)[]>): SuccessMessage
import createUnionType
@MichalLytek MichalLytek added Bug 🐛 Something isn't working Community 👨‍👧 Something initiated by a community labels Mar 28, 2020
@MichalLytek
Copy link
Owner

MichalLytek commented Mar 28, 2020

Unfortunately, that's limitation of TS structural typings and type inference.

Here is an example how fragile it can be:

image

No compile errors, it doesn't complain about missing property and incorreclty narrow the type then, which result in a runtime error.

But I've discovered that using const assertion can fix your problem:

Code_99cvnoai1N

But this requires some changes in type-graphql code, so please wait for a proper fix 😉

BTW, you have an error in the code - instead of:

if ("error" !in value && "accessToken" !in value)

it should be:

if (!("error" in value) && !("accessToken" in value))

@MichalLytek MichalLytek added this to the 1.0.0 release milestone Mar 28, 2020
@MichalLytek
Copy link
Owner

Closing via 2e5f155 🔒 Released in v0.18.0-beta.15 🚀

@MichalLytek MichalLytek added the Solved ✔️ The issue has been solved label Mar 30, 2020
@WimSuenensDIRACIndustries
Copy link
Author

Thanks for the quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🐛 Something isn't working Community 👨‍👧 Something initiated by a community Solved ✔️ The issue has been solved
Projects
None yet
Development

No branches or pull requests

2 participants