I am encountering an issue with typing while coding:
function identity<T>(v: T): T{ return v; }
function execute(fn: {(n: number):string}) {}
execute((n) => {
// type of n is 'number'
return n.toFixed();
})
execute(identity((n) => {
// type of n is 'any'
return n.toFixed();
}))
When a typed higher-order function execute
receives a function, the arguments of that anonymous function are typed via inference. However, passing that anonymous function to a wrapper identity
function causes those inferred types to be lost. Is there any adjustments I could make to the construction of execute
or identity
that can allow those typings to still be inferred?
NOTE For simplicity, identity
is a pure function here. In actual practice it is not, but should have the same typing as this identity
function. See checkpoint
in context of question for more detail.
see it in the TS Playground
Context
This is the generic form of a problem I was facing when handling data within a React component lifecycle. To avoid calling setState
on an unmounted component, I implemented logic to prevent the load callback from executing.
function loadData():Promise<MyDataType> {/*...*/}
// Wraps the passed function (handleDataLoaded),
// such that when the returned function is executed the
// passed function is conditionally executed depending
// on closure state.
function checkpoint(fn){/*...*/}
// Add data to the state of the component
function handleDataLoaded(val: MyDataType){/*...*/}
// react lifecycle hook componentDidMount
loadData()
.then(checkpoint(handleDataLoaded));
// react lifecycle hook componentWillUnmount
// adjusts state of checkpoint's closure such that handleDataloaded
// is not fired after componentWillUnmount