-
Notifications
You must be signed in to change notification settings - Fork 26
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 Improvements #2
Comments
thanks for the input, super apreciated! im going with your instincts, they seem warranted. having this finally infer types is amazing (using use-asset for 1.5 years, but typing was a major pita). i renamed args to keys and documented it accordingly. |
Similarly to what the OP mentioned in one of the approaches (1. b), I was also thinking that one of the better ways to improve type safety is to change the API in a way that enforces creating individual caches, each for a specific pair of @drcmda, I hope you don't mind, but to illustrate what that could look like I created an adapted version of suspend-react based on one of your demos. Basically the adapted api there closes over the loader function and config from the args of the "suspending store" factory: function createSuspendingStore<Keys extends any[], Value>(
fn: (...keys: Keys) => Promise<Value>, config?: Config
): {
suspend(keys: Keys): Value,
preload(keys: Keys): void,
peek(keys: Keys): Value,
clear(keys?: Keys): void
}
const postsStore = createSuspendingStore(fetchPost);
const post = postsStore.suspend([id]); Alternatively the loader function and config could be moved back to the related methods, but consuming them involves a bit more boilerplate: function createSuspendingStore<Keys extends any[], Value>(): {
suspend(fn: (...keys: Keys) => Promise<Value>, keys: Keys, config?: Config): Value,
preload(fn: (...keys: Keys) => Promise<Value>, keys: Keys, config?: Config): void,
peek(keys: Keys): Value,
clear(keys?: Keys): void
}
const postsStore = createSuspendingStore<[number], HNPost>();
const post = postsStore.suspend(fetchPost, [id]); What do you think? |
@drcmda My pleasure! In that case I'll send a PR implementing @miguel-silva Your concern around key collisions is fair, but I think it can be solved easily userland, I opened an issue suggesting how |
@miguel-silva key collisions are easy to avoid, const uid = new Symbol()
suspend(fn, [key1, key2, uid]) i wanted this library to be as simple as humanly possible. cache store already introduce things that aren't so straight forward. |
added a small section in the docs https://github.com/pmndrs/suspend-react#making-cache-keys-unique |
Blocked on microsoft/TypeScript#46724, waiting to see if it's a bug. If it is then will wait till it gets fixed, if it's not a bug then will see if we can do some workarounds. In worst case we can write declaration by hand instead of the making the compiler emit wrong ones. |
I think there is some room for improvement
clear
andpeek
are essentially "untyped".Imagine I'm using this library for fetching two resources A and B, A has dependencies as
[number, number]
and B has dependencies[number, string]
. So I need a way to makeclear(["foo", "bar"])
not compile.In other words I need to pass the type of (global) dependencies (which is
[number, number] | [number, string]
in this case) to the library. So here are the ways to do it...a. Tell users to pass the types via extending an interface via module augmentation
If the user doesn't provide the types we'd fallback to
unknown[]
for dependency.b. Change the API.
c. Add an extra type-safe API.
Same as above except we'd also export the current exports (
suspend
,clear
, etc) along withcreateSuspender
so the folks who don't care about types can directly usesuspend
,clear
, etc without having to usecreateSuspender
d. Don't bother about it, it's not a problem.
Right now you can kinda achieve type-safety like this...
But now you can pass you can pass whatever type different from the actual dependency, you can forget to pass it, you can pass one type to
clear
but other type to the second arg ofsuspend
, etc xDMy recommendation would be to go with a or d
suspend
signature can be improvedThis is not much of a big deal just that right now if you hover over
suspend
this is what you see...We can change the type a bit so that the user sees this instead...
Or even this...
Though these both come with a negligible risk, here's what Ryan said about it... (although the issue he's commenting on is different but I think it still applies)
I think we should keep it as it is I guess there's no much gain for the however small risk incurred, just giving the options anyway :P
Let me know if you like any of these improvements, then I'd send a PR. Or if you're fine as the way things are (no problems in that too ofc) you can close this issue.
Also, I'd suggest to change the nomenclature of "dependencies"/"dependency"/"args" to "key" (singular) as the tuple is the key for the cache, it just happens to be dependencies of the
suspend
function but other than that it doesn't make sense to name the argument ofclear
as "dependencies" or "args". And also you'd want to come up with a name for the function that one passes insuspend
(right now it says "fn"), maybe "resolver"?It's important to get the nomenclature right because even though it doesn't get reflect in the API anywhere, it does in the documentation, types, source, etc.
The text was updated successfully, but these errors were encountered: