nicolasdao / graphql-s2s

Add GraphQL Schema support for type inheritance, generic typing, metadata decoration. Transpile the enriched GraphQL string schema into the standard string schema understood by graphql.js and the Apollo server client.
Other
187 stars 15 forks source link

Generic type in non-nullable typed array doesn't compile #23

Closed ryanmaxwell closed 5 years ago

ryanmaxwell commented 5 years ago

Hi there. Great project. I've noticed the following doesn't work

If you defined a generic type like your examples, but made the generic T non optional, it won't compile.

type Paged<T> {
    data: [T!]!
    cursor: ID
}

type Student {
    name: String
    questions: Paged<Question>
}

Invalid argument exception. Mismatch types between the 'genericType' (${genericType}) and the allowed types 'genericLetters' (${genericLetters.join(',')}).

I also thought I would try the alternative and pass in a non-optional as the T

type Paged<T> {
    data: [T]!
    cursor: ID
}

type Student {
    name: String
    questions: Paged<Question!>
}

but that also fails.

GraphQLError: Syntax Error: Expected Name, found !

I typically like to define my array's generic type as being nonnull, as there usually isn't any good reason for a null value to be in the middle of the data set. Is this something that could be fixed?

Thanks

nicolasdao commented 5 years ago

Thanks for reporting this @ryanmaxwell,

I will try to fix this asap.

Really appreciate your support and your involvement with our little community :)

ryanmaxwell commented 5 years ago

No problem. I feel lazy just reporting bugs without even looking into fixing it so appreciate your time. Ps thinking about it I imagine the second option I tried above is the more correct and flexible solution. The ! Is applied to the concrete type rather than the placeholder and allows consumers of the generic protocol to choose what kind of nullability they want the generic type to have.

ryanmaxwell commented 5 years ago

Reading the error message, it may be as simple as the generated type name which concatenates the value in the angle brackets to the type name just needs to trim the ! off the end.

ryanmaxwell commented 5 years ago

My thoughts were correct. See graphqls2s.js line 151. This statement needs to take the ! off the end of the types before concatenating them

return `${parts[0]}${m[1].split(',').map(x => x.trim()).join('')}\\`

This did the trick for me but you could probably write a regex to both trim whitespace at the start and end and any ! in one go, i'm pretty bad at regex...

return `${parts[0]}${m[1].split(',').map(x => x.trim().replace(/!\s*$/, '')).join('')}`
nicolasdao commented 5 years ago

Hi @ryanmaxwell ,

I've just fixed that issue. Try to update to the latest version (0.17.3) and let me know how that goes.

Thanks a lot for your patience.

Cheers,

Nic