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

typescript is incorrect when using different fetchers but the same key #2925

Open
tjallingt opened this issue Mar 27, 2024 · 3 comments
Open

Comments

@tjallingt
Copy link

tjallingt commented Mar 27, 2024

Bug report

Description / Observed Behavior

import useSWR from "swr";

async function fetchOne(key: string): Promise<string> {
  return "1";
}

async function fetchTwo(key: string): Promise<number> {
  return 2;
}

export default function One() {
  let { data } = useSWR("test", fetchOne);

  if (data != null) {
    data.charCodeAt(0); // Error: data.charCodeAt is not a function
  }

  return (
    <>
      <div>one {data}</div>
      <Two />
    </>
  );
}

function Two() {
  let { data } = useSWR("test", fetchTwo);

  return <div>two {data}</div>;
}

results in

Error: data.charCodeAt is not a function

Despite having no TypeScript errors

Expected Behavior

one 1
two 2

Repro Steps / Code Example

https://codesandbox.io/p/sandbox/test-swr-mfvvvg

Additional Context

SWR version: 2.2.4 & 2.25

@tjallingt tjallingt changed the title error in one fetcher can be overwritten with result from another typescript when using different fetchers but the same key Mar 27, 2024
@tjallingt tjallingt changed the title typescript when using different fetchers but the same key typescript is incorrect when using different fetchers but the same key Mar 27, 2024
@garyhuntddn
Copy link

Ha ha - I can see what you’d like it to do, but that’ll never be possible given that typescript is a facade on top of JavaScript - you’re telling it what you expect, but in no way is the JavaScript contracted to do that.

the general use case of swr is to call fetch, and most assume that the json they then attempt to cast into a type will conform to that type - but that won’t be the case on many occasions. Therefore always treat swr as an api boundary and never trust the results to be what you hope them to be.

in this particular example you’ve simply used the same cache key (‘test’) for multiple things and any library would suffer the same problem.

@tjallingt
Copy link
Author

But I would expect the fetcher to, implicitly, be part of the cache key. So that "test" + "fetchOne" is cached in a different slot than "test" + "fetchTwo". That would also fix the error with the types.

@garyhuntddn
Copy link

I've never seen it done - but there's no harm in you creating your own standard...

const { data } = useSWR( [ "test", fetchOne ], fetchOne);

and

const { data } = useSWR( [ "test", fetchTwo ], fetchTwo);

Would then include the fetcher in the key - but once again - remember that in real world use - what gets returned from a cache of any kind might not be what you expect - so you should code more defensively and expect the unexpected.

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

No branches or pull requests

2 participants