swr icon indicating copy to clipboard operation
swr copied to clipboard

`data` for nullish keys with `suspense: true` should have the `undefined` type

Open nstepien opened this issue 1 year ago • 6 comments

Bug report

Description / Observed Behavior

  const { data } = useSWR<MyType>(
    condition ? null : 'url',
    { suspense: true }
  );

Since [email protected] with the snippet above, data is MyType when it should be MyType | undefined because the key may be null.

Expected Behavior

useSWR should handle nullish keys and return the correct type.

Repro Steps / Code Example

See above

Additional Context

SWR version: 2.1.0

I believe this type bug affects suspense: true, but when fallbackData is set then data can never be undefined, so they should be handled appropriately.

nstepien avatar Mar 07 '23 12:03 nstepien

Even if the key was always a valid url, data should have | undefined in its type because its value should be undefined while waiting for the request response.

See https://github.com/vercel/swr/issues/2516#issuecomment-1479910033

rosedo avatar Mar 23 '23 09:03 rosedo

@rosedo data can't be undefined when using suspense: true

nstepien avatar Mar 23 '23 11:03 nstepien

I am using suspense true and fallbackData and still the type is undefined

irg1008 avatar Apr 11 '23 07:04 irg1008

@nstepien I don't know about the suspense option, but I'll just say that it's OK for typescript to have types that include more than reality. It's still better than javascript this way. That's why I'm not fond of the idea of having 8 different type signatures for a single function. It seems like over-engineering, even for a library.

What's not OK is for typescript to lie about return types. If undefined is not an option in a return type and you end up getting undefined at execution it's not OK.

If you want to remove undefined from the return type then you should check that the function behavior never returns undefined for the allowed input param types.

rosedo avatar Apr 11 '23 08:04 rosedo

it's OK for typescript to have types that include more than reality.

It's not OK to have incorrect types. If a function cannot return undefined, conditionally or otherwise, then it shouldn't be typed as such.

nstepien avatar Apr 11 '23 10:04 nstepien

I also just happened to have bumped into this issue while upgrading to the latest version of SWR.

What's more, typing it out like

useSWR<Data, Key, {suspense: true}>(key, { dedupingInterval: 5000, suspense: true })

Gives a TypeScript error that no overload matches the call and we have to explicitly extend SWRConfiguration to include a always true suspense.

No overload matches this call. The last overload gave the following error. Object literal may only specify known properties, and 'dedupingInterval' does not exist in type '{ suspense: true; }'.ts(2769)

I believe the conditional typing of data is still somewhat incomplete and can be improved on.

muqg avatar Apr 29 '24 07:04 muqg