问题
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