Skip to content
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

axios-typescript exemple doen't work #238

Closed
vcombey opened this issue Jan 19, 2020 · 8 comments · Fixed by #265
Closed

axios-typescript exemple doen't work #238

vcombey opened this issue Jan 19, 2020 · 8 comments · Fixed by #265

Comments

@vcombey
Copy link

vcombey commented Jan 19, 2020

after copied in my project the useRequest fonction from the axios-typescript exemple typescript give me this error.
/app/src/useRequest.tsx

/app/src/useRequest.tsx
TypeScript error in /app/src/useRequest.tsx(30,69):
Argument of type '{ initialData: { status: number; statusText: string; config: GetRequest; headers: {}; data: Data; } | undefined; onError?: ((err: AxiosError<Error>, key: string, config: ConfigInterface<...>) => void) | undefined; ... 14 mor
orRetry?: ((err: AxiosError<...>, key: string, config: ConfigInterface<...>, reva...' is not assignable to parameter of type 'ConfigInterface<AxiosResponse<Data>, AxiosError<Error>, fetcherFn<AxiosResponse<Data>>>'.
  Types of property 'initialData' are incompatible.
    Type '{ status: number; statusText: string; config: GetRequest; headers: {}; data: Data; } | undefined' is not assignable to type 'AxiosResponse<Data> | undefined'.
      Type '{ status: number; statusText: string; config: GetRequest; headers: {}; data: Data; }' is not assignable to type 'AxiosResponse<Data>'.
        Types of property 'config' are incompatible.
          Type 'GetRequest' is not assignable to type 'AxiosRequestConfig'.
            Type 'null' is not assignable to type 'AxiosRequestConfig'.  TS2345

    28 |     AxiosResponse<Data>,
    29 |     AxiosError<Error>
  > 30 |   >(request && JSON.stringify(request), () => axios(request || {}), {
       |                                                                     ^
    31 |     ...config,
    32 |     initialData: initialData && {
    33 |       status: 200,

Im using axios 0.19.1 and swr 0.1.16.
Im totaly new to this ecosystem, and those errors looks scary for me. what is the problem, is that a version problem ?

@sudkumar
Copy link

@vcombey I don't see any problem with the implementation. The errors should not exists. I will first explain what the error is saying:

The axios's default export is a function that can be called with a AxiosRequestConfig type config object.

const config: AxiosRequestConfig = {}
axios(config)

This config CAN NOT BE null. In the implementation, at line number 30, we can see axios(request || {}). Here we have {} as the fallback option because our request is of type GetRequest = AxiosRequestConfig | null, but as mentioned earlier, axios does not accept the null values for it's configuration parameter. The implementation accepts the null value for the request because swr will not call the fetchMethod () => axios(request || null), if its first argument is null. see docs.

So why are you seeing this error. For that, we need to know the typescript version that you are using. I have tested it on typescript: v3.7..2 and it is working. see playground

npm list typescript

If you just want a solution, you can force a type cast as following

-   >(request && JSON.stringify(request), () => axios(request || {}), {
+   >(request && JSON.stringify(request), () => axios((request || {}) as any as AxiosRequestConfig), {

Hope it helps

@Svish
Copy link
Contributor

Svish commented Feb 15, 2020

Yeah, the code works fine, but depending on how strict you've configured Typescript and your eslint settings, you might get complaints because Axios does not accept null as config, and Typescript (correctly) believes it can be null. However, we know that it actually can't be null, because we know useSWR will only actually call it when it is not.

So, the fix, is simply to tell Typescript that we know it will not be null. Simplest way to do that is via the non-null operator(?), !, like this:

    () => axios(request!),

I made a PR to update the example with this tweak. 🙂

@vcombey
Copy link
Author

vcombey commented Feb 16, 2020

Ok, thanks verry much for the explanations and the solution. Indeed I had configured typescript with "strict: false" to make him happy with the current example

@giovanniantonaccio
Copy link

I still get the same error mentioned on this issue. Any tips to fix this?

@sudkumar
Copy link

@giovanniantonaccio Can you please provide the error output and the source code for the fetch method?

@giovanniantonaccio
Copy link

@sudkumar I just coppied the exact same code from this example: https://github.com/zeit/swr/blob/master/examples/axios-typescript/libs/useRequest.ts

And I get this error in initialData:

TypeScript error in /Users/giovanniantonaccio/Dev/www/swrtest/src/useRequest.ts(40,7):
Type '{ status: number; statusText: string; config: GetRequest; headers: {}; data: Data; } | undefined' is not assignable to type 'AxiosResponse<Data> | undefined'.
  Type '{ status: number; statusText: string; config: GetRequest; headers: {}; data: Data; }' is not assignable to type 'AxiosResponse<Data>'.
    Types of property 'config' are incompatible.
      Type 'GetRequest' is not assignable to type 'AxiosRequestConfig'.
        Type 'null' is not assignable to type 'AxiosRequestConfig'.  TS2322

    38 |     {
    39 |       ...config,
  > 40 |       initialData: initialData && {
       |       ^
    41 |         status: 200,
    42 |         statusText: 'InitialData',
    43 |         config: request,

@sudkumar
Copy link

@giovanniantonaccio Looks like there IS an issue with the initialData.

https://github.com/zeit/swr/blob/bf01052c00078fdbd958cb038eb5d857c24a0605/examples/axios-typescript/libs/useRequest.ts#L40-L45

The type of initialData is AxiosResponse<Data> | undefined'. The undefined is getting resolved with the initialData && condition. When there is an initialData via props, AxiosResponse<Data> should be the response but the config key in the initialData has conflicts because it is assigned the value of request which can be null but null is not allowed in AxiosResponse for the config key.

A quick way to resolve this would be letting the typescript know that it's OKAY for config to be null in initialData which is OK for most of the cases.

initialData: initialData && {
.
-   config: request
+   config: request!
.
}

Hope it helps. Please feel free to ask if there are any queries.

@giovanniantonaccio
Copy link

Thanks @sudkumar, this solved the problem!

shuding pushed a commit that referenced this issue Jul 21, 2020
wroy7860 added a commit to wroy7860/ReactandNode-develop-swr-core-infinate- that referenced this issue Sep 19, 2022
johnfrench3 pushed a commit to johnfrench3/swr-react-dev that referenced this issue Nov 2, 2022
renawolford6 added a commit to renawolford6/swr-core-test-javascript that referenced this issue Nov 10, 2022
codechieflee added a commit to codechieflee/react-hook-swr that referenced this issue Aug 19, 2023
muscliary pushed a commit to muscliary/swr that referenced this issue Sep 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants