There appears to be an undocumented feature which allows functions to infer a type from a function in which they are passed as an argument.
I'm trying to understand why this works, and if it's intentional.
Given a Model, then with a generic update and apply function, I can infer a type from apply when using the result of update as an argument with the trick T extends infer U ? U : never:
interface Model {
foo: number
bar: string
}
function apply<T>(fn: (t: T) => T) {};
function whyDoesThisWork() {
function update<T>(u: T extends infer U ? Partial<U> : never) { return (t: T) => ({ ...t, ...u }) };
// Somehow, Typescript is able to infer that we want Model to be the generic supplied for update
apply<Model>(update({ foo: 1 }));
}
function thisDoesntWorkForObviousReasons() {
function update<T>(u: Partial<T>) { return (t: T) => ({ ...t, ...u }) }
// update infers T as { foo: 1 }, because that makes sense
apply<Model>(update({ foo: 1 }));
}