问题
I want to write a type constructor for a function which receives a type S
and a function from S
to another type then applies that function on the S
and returns the result:
// This works but it's tied to the implementation
function dig<S, R>(s: S, fn: (s: S) => R): R {
return fn(s);
}
// This works as separate type constructor but I have to specify `R`
type Dig<S, R> = (s: S, fn: (s: S) => R) => R;
// Generic type 'Dig' requires 2 type argument(s).
const d: Dig<string> = (s, fn) => fn(s);
So how can I write a Dig<S>
type constructor which infers the return type of the passed fn
argument without me specifying the R
?
回答1:
As of TS3.4 there is no support for partial type argument inference, so you can't easily have the compiler let you specify S
but infer R
. But from your example, it doesn't look like you want to infer R
as some concrete type, but allow it to remain generic so that the return type of fn
can be whatever it wants to be when you call d()
.
So it looks like you really want this type:
type Dig<S> = <R>(s: S, fn: (s: S) => R) => R;
This is sort of a "doubly generic" type, in the sense that once you specify S
you've still got a generic function dependent on R
. This should work for the example you gave:
const d: Dig<string> = (s, fn) => fn(s);
const num = d("hey", (x) => x.length); // num is inferred as number
const bool = d("you", (x) => x.indexOf("z") >= 0); // bool inferred as boolean
Okay, hope that helps. Good luck!
来源:https://stackoverflow.com/questions/55655707/typescript-infer-the-callback-return-type-in-type-constructor