"The caller of the function specifies the type parameter, not the implementer"
If you refer back to my TypeScript version please note that I require Promise<T>.
Your version only gives me Promise<unknown>. The moment I put Promise<T> on rootAndRun() everything lights up red. The Promise<T> based on Factory<T> was the point of making rootAndRun() generic.
For Promise<unknown> we don't need generics to begin with. CodeSandbox
unknown is extremely useful under very specific circumstances but when overused it reminds me of the Java pre-Generic Object fiasco in terms of type safety.
that could be reused
How OO of you 😁
In this case reuse isn't the goal as this is only for testing support, so not being coupled via reuse (Beware of the Share) is a good thing.
Also in general I try to stick to the Rule of Three:
You must have looked at at least three systems to understand what is common across them (and therefore reusable)
It takes three times as much effort to make something reusable as to make it usable
You will receive payback after the third release.
In this case the goal was to "unroll" it enough to make it more understandable.
Here's your CodeSandbox with the minimum fixes I would do to it. The problems I saw:
executor had its own T instead of using the one from rootAndRun and Factory, so that will be taken as different generics even if you name them the same. You can see this by just renaming T to something else (F2).
done has the same problem.
resolve inside done expects T, but done actually passes data as T | undefined, so you have to check if data is defined before passing it to resolve.
Other than that I just added Maybe (an alias for Type | undefined that I always have around), and made some changes here and there to make my linter happy (like using error instead of err).
How OO of you 😁
Trust me, FP is all about reuse. I don't follow a "rule of N", I just try to keep my functions small and make them do one job and do it right which makes them far easier to test, maintain and reuse.
So my "type parameters inside closures" needs more work; figures. The Maybe makes sense, I'm constantly surprised it's not with the utility types.
I just try to keep my functions small and make them do one job and do it right which makes them far easier to test, maintain …
I'm right there with you in terms of small and focused but I'm not prescient so it's far too easy for me to fall prey to premature reuse/abstraction—OO or functional.
Thank You for the assist!
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
TIL: There needs to be a comma after the type parameter for an arrow function otherwise TS thinks it's JSX.
The error message I was fighting:
"Argument of type
T
is not assignable to parameter of typeT
.T
could be instantiated with an arbitrary type which could be unrelated toT
."CodeSandBox
Which seems to imply:
"The caller of the function specifies the type parameter, not the implementer"
If you refer back to my TypeScript version please note that I require
Promise<T>
.Your version only gives me
Promise<unknown>
. The moment I putPromise<T>
onrootAndRun()
everything lights up red. ThePromise<T>
based onFactory<T>
was the point of makingrootAndRun()
generic.For
Promise<unknown>
we don't need generics to begin with. CodeSandboxunknown
is extremely useful under very specific circumstances but when overused it reminds me of the Java pre-GenericObject
fiasco in terms of type safety.How OO of you 😁
In this case reuse isn't the goal as this is only for testing support, so not being coupled via reuse (Beware of the Share) is a good thing.
Also in general I try to stick to the Rule of Three:
In this case the goal was to "unroll" it enough to make it more understandable.
Here's your CodeSandbox with the minimum fixes I would do to it. The problems I saw:
executor
had its ownT
instead of using the one fromrootAndRun
andFactory
, so that will be taken as different generics even if you name them the same. You can see this by just renamingT
to something else (F2).done
has the same problem.resolve
insidedone
expectsT
, butdone
actually passesdata
asT | undefined
, so you have to check ifdata
is defined before passing it toresolve
.Other than that I just added
Maybe
(an alias forType | undefined
that I always have around), and made some changes here and there to make my linter happy (like usingerror
instead oferr
).Trust me, FP is all about reuse. I don't follow a "rule of N", I just try to keep my functions small and make them do one job and do it right which makes them far easier to test, maintain and reuse.
So my "type parameters inside closures" needs more work; figures. The
Maybe
makes sense, I'm constantly surprised it's not with the utility types.I'm right there with you in terms of small and focused but I'm not prescient so it's far too easy for me to fall prey to premature reuse/abstraction—OO or functional.
Thank You for the assist!