-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Better Typing support when suspense is enabled #1412
Comments
Already fixed in https://github.com/vercel/swr/releases/tag/1.0.1-beta.0 ??? |
No it’s not added yet. I don’t think this can be handled by TypeScript because configs can be inherited from |
My suggestion would be to just separate the two. Either a separate hook, or just a separate import like from That way you could simplify the regular hook by removing all suspense related stuff from there, and the suspense hook could be written with perfect types and no non-suspense related stuff. |
What should happen if <SWRConfig value={{ suspense: false }}>
<App />
</SWRConfig> |
Can't you already do that? Doesn't useSWR currently take suspense as an option, which overrides the default config? |
By definition, Also, it would be great to cover more use cases such as waterfall (#5, #168) and dependents with this suspense hook. Waterfall: useSWRSuspense(key1)
useSWRSuspense(key2) Dependent (should it fallback to the suspending state if the first resource changes upon focus?): const { data } = useSWRSuspense(key1)
useSWRSuspense(data.id) |
OK, so your proposal is for the new How should then conditional fetching be solved? Suspense users should also be allowed to make conditional requests, therefore We can, however, leverage declare function useSWR<T>(key: string): { data: T };
declare function useSWR<T>(key: string | null): { data: T | undefined };
declare function safestring(strings: TemplateStringsArray, ...args: Array<string | number>): string;
declare function safestring(strings: TemplateStringsArray, ...args: Array<string | number | null | undefined>): string | null;
declare function safestring(strings: TemplateStringsArray, ...args: Array<string | number | null | undefined>): string | null;
declare const customerId: string | null;
useSWR<Response>(safestring`/api/v1/customers`).data; // Response
useSWR<Response>(safestring`/api/v1/customers/${customerId}`).data // Response | undefined |
Is there any workaround right now, where I can tell SWR that the data will be guaranteed to be defined, thanks to suspense and error boundaries? |
Best solution now is probably to make your own typed wrapper hook of useSWR which makes sure things work the way you want. We've done this for react-query, works well. |
I don't know the internals of useSWR, but couldn't one in principle use overloading to infer if data is defined or not? Something equivalent to this? function useSWR<Data>(key:undefined, fetcher: Function): {data: undefined};
function useSWR<Data>(key:string, fetcher: Function): {data: Data};
function useSWR<Data>(key:string | undefined, fetcher: Function): {data: Data | undefined} {
// code
} |
@MoSattler There is a problem with such an overload. Reason: Consider this common use case: useSWR(`/customers/${customerId}`, fetcher) If |
How so? Wouldn't the string evaluate to |
Why make a call you know will fail?
It is not, and that the reason why we have #1247 in the first place. |
I believe OP and myself are asking for the typing to properly reflect the current implementation, not possible future changes that may or may not come. In the current implementation it seems to be true that |
Is there any way to get some movement on this? Seems the discussion died down. |
Is this issue open to contributions? I've done a quick test override and something like this seems to work fine. Added bonus of adding inference for return types + keys passed to the handler. // swr.d.ts
import { SWRResponse, KeyedMutator } from 'swr';
declare module 'swr' {
type SWRHook1 = <
Key extends SWRKey,
Data extends any,
Config extends { suspense: boolean }
>(
key: Key,
handler: (arg: Key) => Promise<Data>,
config: Config
) => Config['suspense'] extends true
? SWRResponseSuspense<Data>
: SWRResponse<Data, Error>;
type SWRResponseSuspense<D> = { data: D, mutate: KeyedMutator<D> }
declare const _default: SWRHook1;
export = _default;
} |
This looks like a great feature to be used in the new React 18 update! It would be great if someone implemented it. |
Some restrictions can be applied to swr when suspense is enanbled:
key
can’t be falsyfetcher
can’t be nulldata
can’t be undefinedNote: this is tricky as TypeScript can’t handle inherited configs, and those can be dynamic in the runtime.
The text was updated successfully, but these errors were encountered: