-
Notifications
You must be signed in to change notification settings - Fork 17
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
Validate that all context types match #29
Conversation
✅ Deploy Preview for grats ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
@@ -50,7 +50,6 @@ | |||
- [ ] Improve playground | |||
- Could we actually evaluate the resolvers? Maybe in a worker? | |||
- Could we hook up GraphiQL 2? | |||
- [ ] Can we ensure the context and ast arguments of resolvers are correct? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe premature to add this since we don't yet typecheck the info
argument.
@@ -980,7 +985,7 @@ export class Extractor { | |||
} else if (node.kind === ts.SyntaxKind.FalseKeyword) { | |||
return this.gql.boolean(node, false); | |||
} else if (ts.isObjectLiteralExpression(node)) { | |||
return this.cellectObjectLiteral(node); | |||
return this.collectObjectLiteral(node); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated typo fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very exciting this change! I was thinking (maybe you though this too) Grats could also support the @gqlContext
docblock tag, so when present, all ctx
arguments' type must resolve to that, otherwise, use this checking strategy as fallback.
----------------- | ||
OUTPUT | ||
----------------- | ||
src/tests/fixtures/resolver_context/MultipleContextValuesUsed.invalid.ts:16:34 - error: Context argument's type does not match. Grats expects all resolvers that read the context argument to use the same type for that argument. Did you use the incorrect type in one of your resolvers? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should explain that Grats needs the exact same type reference (instead of structurally equivalent types) because it doesn't perform typechecking on the ctx
arguments' type. Any user with TS experience will look at GratsContext
and AlsoGratsContext
and think "but, they are the same!" but "same" in this context means different things when Grats is checking the schema and when TS checks the code.
----------------- | ||
src/tests/fixtures/resolver_context/ContextValueTypedAsString.invalid.ts:4:30 - error: Expected context parameter's type to be a type reference Grats validates that your context parameter is type-safe by checking all context values reference the same type declaration. | ||
|
||
4 greeting(args: never, ctx: string): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is not supporting string
intentional? Or is it because some technical limitation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technical limitation because we are tracking the definition of the type, and primitives and literals won't work.
----------------- | ||
src/tests/fixtures/resolver_context/ContextValueTypedAsNever.ts:4:30 - error: Expected context parameter's type to be a type reference Grats validates that your context parameter is type-safe by checking all context values reference the same type declaration. | ||
|
||
4 greeting(args: never, ctx: never): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it not possible to allow unknown
as the type for ctx
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, just haven't added it yet! Unclear if it's needed though. I guess if you need to access the info
argument after the context value and you don't actually ever use the context value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's one use case. It would be a just escape hatch, in case we need to add the context argument (for whatever reason) but we don't want to deal with typing the context right now.
However, if it's easy to add, we could not add it now, and wait for (less theoretical, more practical) reasons to add it and make a better decision then.
Yeah, I had a similar thought but more sequential than options. We can start here, and if we end up needing to actually know which value is the context value (say for positional arguments) we could layer on the |
I think all modes are valid, it just adds some complexity to the checking code:
I can see this working great, as long as if a check fails the error message is descriptive enough to explain what and why, and provide actions or suggestions. |
@@ -161,11 +161,11 @@ export function typeNameDoesNotMatchExpected(expected: string) { | |||
} | |||
|
|||
export function argumentParamIsMissingType() { | |||
return "Expected GraphQL field arguments to have a TypeScript type. If there are no arguments, you can use `args: never`."; | |||
return "Expected GraphQL field arguments to have a TypeScript type. If there are no arguments, you can use `args: unknown`."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check/guidance was wrong before, but I'm fixing it here. Should have been unknown
for this use case not never
.
@@ -22,7 +22,7 @@ const config = { | |||
projectName: "grats", // Usually your repo name. | |||
|
|||
onBrokenLinks: "throw", | |||
onBrokenMarkdownLinks: "warn", | |||
onBrokenMarkdownLinks: "throw", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Errors were turning up in CI but not local dev. This fixes that.
Fixes #21. Directly implements what @mandx suggested in #21 (comment).
An alternative
/** @gqlContext */
approach is explored in #24.