-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Fix/ts resolvers type #5437
Fix/ts resolvers type #5437
Conversation
✅ Deploy Preview for redwoodjs-docs canceled.
|
Just a little headsup on this fix - it has a downside... explained here: https://s.tape.sh/nK9CgxZt I'm trying a couple of other things to see if I can find another way |
run: | | ||
yarn rw type-check | ||
working-directory: ${{ steps.setup_test_project.outputs.test_project_path }} | ||
|
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.
Depending on how thorough you want to be here, you could switch strict to be true in the tsconfig to really ensure things are valid for all consumers
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.
Hmmm good point! I don’t think I’ve ever tried it in strict mode 😂
@orta I was thinking of another approach - wanted your thoughts on it! If we made ResolverFn an interface (probably would need to change stuff in codegen) - then, Only for jest, override this interface two have two forms:
What do you think? |
After watching the video, I'm not super sold on making both params optional. It's gonna require either using The reason it feels inelegant is because the redwood generators recommend using argument destructuring to hide the actual object, if it was just an
|
Yeah totally agree - I feel icky from trying it |
Yeah, interesting approach, I'm not too certain how that would work out form the top of my head. Something like:
to
Which should probably set up two callable functions overloads externally when using resolver inside the type, then because you have passed some arguments in during implementation TS would narrow to the right one in resolver implementation, and you probably get the choice from outside the module to just pass nothing in |
Ah that’s a good idea - not sure why I was thinking of an interface! I’ll give it a try in an hour or so! |
Ah just remembered. Interface because I only want to override the type for jest tests, and not the actual source. Getting codegen to generate an interface on the other hand could be a challenge! |
Here's what I tried: type OGResolver<TResult, TParent, TContext, TArgs> = (
args: TArgs,
obj?: { root: TParent; context: TContext; info: GraphQLResolveInfo }
) => Promise<Partial<TResult>> | Partial<TResult>
type ResolverFnForTests<TResult> = () =>
| Promise<Partial<TResult>>
| Partial<TResult>
export type ResolverFn<TResult, TParent, TContext, TArgs> =
| ResolverFnForTests<TResult>
| OGResolver<TResult, TParent, TContext, TArgs> Unfortunately looks like TS doesn't narrow correctly I tried the interface approach too, like this: // eslint-disable-next-line @typescript-eslint/no-unused-vars
interface ResolverFn<TResult, TParent, TContext, TArgs> {
(): Promise<Partial<TResult>> | Partial<TResult>
}
interface ResolverFn<TResult, TParent, TContext, TArgs> {
(
args: TArgs,
obj?: { root: TParent; context: TContext; info: GraphQLResolveInfo }
): Promise<Partial<TResult>> | Partial<TResult>
} This one has the inverse problem, where I think its also picking the wrong interface (the ts error is gibberish) but instead of in the test, in the actual source. I also realised I can't just override types for just Jest... must've gotten confused. |
Ok - so I've looked into strict mode more - and here's my take on this. a) Strict mode just throws errors all over the place - including from Prisma, auth, directives, etc. I know this probably sounds like a cop out to you Orta, but my gut says that people using strict mode know what they're buying into, and would be ok with dealing with the additional headache of maybe overriding the resolver type, and adding empty objects in tests. i.e. they opt-in to more complexity b) I still think making the resolver function params optional (this PR's implementation) is the lesser of two evils, as icky as it is. It resolves the issue, and without strict mode, you still have access to args and info, root, etc. with no changes to your code in either source or test. c) Even if the rest of the team agreed to add I'll sleep on this, would love some more opinions! |
Aye, it's only the lesser problem from the perspective of writing a test - but but when making them optional, you make using strict mode very hard to use. In my app, switching to this breaks every resolver because you have to prove the existence of those params in the real code. e.g. can't use destructuring And you'd you have to put |
Yes I'm thinking (in a separate PR) I'll add some docs and a config flag to generate a different ResolverFn for strict mode. For now though you could override the resolver type by adding a codegen.yaml to the root of your project |
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.
Spent some time trying to get that function overload working as well; came back empty handed, but still holding out hope we can resolve something sometime soon, maybe in collaboration with the guild. After this, we'll make a concerted effort towards strict mode to make sure it's not an afterthought but a legitimate redwood workflow.
Right now we see this as a fix for type-check
. But we'll continue discussing it more tomorrow at the meeting.
To be continued in #5481 |
* Make resolvers callable, args are optional * Add g sdl to ci, reorder type-check * Update snapshot * Make args optional too * Dont print unused mappers Co-authored-by: Dominic Saadi <32992335+jtoar@users.noreply.github.com>
…ctmode-gen * 'main' of github.com:redwoodjs/redwood: Update yarn.lock fix(deps): update graphql-tools monorepo (redwoodjs#5487) v1.3.2 Update yarn.lock fix: Run dedupe during upgrade on yarn 3 (redwoodjs#5458) Fix/ts resolvers type (redwoodjs#5437) fix(deps): update dependency graphql to v16.5.0 (redwoodjs#5488) fixed typo of roll to role (redwoodjs#5484) fix(deps): update typescript-eslint monorepo to v5.23.0 (redwoodjs#5489) chore(deps): update dependency cypress to v9.6.1 (redwoodjs#5482) chore(deps): update dependency firebase to v9.8.1 (redwoodjs#5485) fix(deps): update dependency @types/aws-lambda to v8.10.97 (redwoodjs#5486) chore(deps): update dependency @nhost/nhost-js to v1.1.10 (redwoodjs#5479) chore(deps): update dependency @nhost/hasura-auth-js to v1.1.5 (redwoodjs#5478) Fixing type for BrowserOnly children (redwoodjs#5475) fix: Run dedupe during upgrade on yarn 3 (redwoodjs#5458) Fix/ts resolvers type (redwoodjs#5437)
* Make resolvers callable, args are optional * Add g sdl to ci, reorder type-check * Update snapshot * Make args optional too * Dont print unused mappers Co-authored-by: Dominic Saadi <32992335+jtoar@users.noreply.github.com>
Closes #5370
What does this PR do?
makeResolverTypeCallable: true
to graphql-codgen configobj
optional, because we don't use it in testing.This is a little dubious, because obj is always included when actually using the resolving, but it just feels like a lot of extra code when testing services to pass an empty object.
3. Adds g sdl to CI, and moves typecheck to the end so we check all the generated code (so this sort of regression doesn't happen again)
Just a little headsup on this fix - it has a downside... explained here: https://s.tape.sh/nK9CgxZt
Please read comments in the PR