My typescript code like below: (within typescript 4.4)
export function convert<T extends (...args: any[]) => any>(
func: T
): (_this: ThisParameterType<T>, ...args: OmitThisParameter<Parameters<T>>) => ReturnType<T> {
return Function.call.bind(
Function.bind,
Function.call
)(func) as (_this: ThisParameterType<T>, ...args: OmitThisParameter<Parameters<T>>) => ReturnType<T>;
}
but when i use it like this:
// mark 1
const arrayShift = convert([].shift);
// expect: const shifted: string
const shifted = arrayShift(["1"]); // const shifted: undefined
// mark 2
const arrayMap = convert([].map);
// expect (parameter) e: string
arrayMap(["1"], (e) => { // (parameter) e: never
return parseInt(e, 10);
});
How to got expected type with modify the function named 'convert'?
I managed to achieve it with a 2-step approach. The convert
returns a function, which you can call, with or without arguments.
function convert<A extends Array<T>, T extends any, K extends keyof Array<T>>(
array: A extends Array<infer U> ? Array<U> : Array<T>,
key: K,
) {
function convertArray<A extends Array<T>, T extends any>(
array: A extends Array<infer U> ? Array<U> : Array<T>,
key: K,
) {
return array[key]
}
return function<S extends Array<Y>, Y extends any>(
subjectedArray: S extends Array<infer SK> ? Array<SK> : Array<Y>,
args?: any[] // not yet figured out to call convertArray with args and keep types
) {
return (convertArray<S, Y>(
subjectedArray,
key
))
}
}
const arrayShift = convert([], 'shift')
const arrayMap = convert([], 'map')
const empty = arrayShift([])() // const empty: undefined
const shifted = arrayShift(["123"])() // const shifted: string | undefined
const mapped = arrayMap(["1"])(e => { // (parameter) e: string
return parseInt(e, 10);
}) // const mapped: number[]
type Car = {
engine: 'petrol' | 'gasoline'
}
const cars: Car[] = []
const emptyCars = arrayShift(cars)() // const emptyCars: Car | undefined
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.