-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Update Context Types #12104
base: main
Are you sure you want to change the base?
Update Context Types #12104
Conversation
👷 Deploy request for apollo-client-docs pending review.Visit the deploys page to approve it
|
✅ Docs Preview ReadyNo new or changed pages found. |
🦋 Changeset detectedLatest commit: 4fe7305 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@@ -474,7 +475,7 @@ export class ApolloClient<TCacheShape> implements DataProxy { | |||
public mutate< | |||
TData = any, | |||
TVariables extends OperationVariables = OperationVariables, | |||
TContext extends Record<string, any> = DefaultContext, | |||
TContext extends OperationContext = Partial<DefaultContext>, |
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 created a new type called OperationContext
to represent Record<string, any>. I wanted to call it Context
but
apollo-client/src/react/types/types.ts
Line 43 in 6496b25
export type { DefaultContext as Context } from "../../core/index.js"; |
export function setContext< | ||
TContext extends OperationContext = Partial<DefaultContext>, | ||
>(setter: ContextSetter<TContext>): ApolloLink { |
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.
Update the types here to reflect that users only need to pass in a partial of the context.
apollo-client/src/link/utils/createOperation.ts
Lines 8 to 15 in 4ebebf0
const setContext: Operation["setContext"] = (next) => { | |
if (typeof next === "function") { | |
context = { ...context, ...next(context) }; | |
} else { | |
context = { ...context, ...next }; | |
} | |
}; | |
const getContext: Operation["getContext"] = () => ({ ...context }); |
But I also thought that users might want to strictly type what they want to return here so I've given the flexibility to pass in TContext.
query, | ||
fetchPolicy, | ||
errorPolicy = "none", | ||
variables, | ||
context = {}, | ||
context = {} as TContext, |
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'm not particularly sure what the defaulting is for here but I decided to leave it in to avoid any breaking change and am choosing to cast here instead.
Not sure why the tests are failing as there are no code changes in this PR |
Should this be required? If we're typing DefaultContext, I would expect this to be filled on client creation? apollo-client/src/core/ApolloClient.ts Line 119 in 6496b25
If they need it to be optional they could declare it themselves while extending it |
Hi Sam, |
No problems, we're all busy people! Fully understand, thanks for the reply |
@@ -116,7 +117,7 @@ export interface ApolloClientOptions<TCacheShape> { | |||
* See this [example object](https://www.apollographql.com/docs/react/api/core/ApolloClient#example-defaultoptions-object). | |||
*/ | |||
defaultOptions?: DefaultOptions; | |||
defaultContext?: Partial<DefaultContext>; | |||
defaultContext?: DefaultContext; |
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 this makes sense, if you are expecting something to always be in here, you would declare it as Required on the default context?
Unless we're intentionally making this Partial so you could type things like headers: Record<string, string>
as Apollo seems to always inject these
Checklist:
The tl;dr
context
type on all operations must now extendOperationContext
(Record<string, any>
) and defaults toPartial<DefaultContext>
context
field now requires a non partialDefaultContext
.In Depth
I was trying to work with @phryneas comment here: apollographql/apollo-client-nextjs#103 (comment)
by setting a
defaultContext
type:eg.
However, this had cascading effects to the other operations such as useQuery where suddenly the operation inputs were expecting
appContext
to be in the context which is incorrect as we should only require a partial of the default context to allow for overwritingSo I decided to go and fix the query type but realised the mutation type allows the Context to be set:
apollo-client/src/core/watchQueryOptions.ts
Line 252 in 6496b25
So in the name of consistency I went to try and add generics for the Query types and many changes later here we are.