简体   繁体   中英

Infer parameter types in function chain

I'm trying to make a home made function mapping chain. Thing is, I want to make sure typing stays consistent trough the mapping chain. My problem is that I don't know how to write f(x:T) => U

For a proper example of what I'm trying to do:

function myChainer<T>(args:T){
    return {
       map:(innerFuction:(payload: T) => unknown){
           return myChainer(innerFuction(args))
       }
    }
}

Now, if I run

myChainer(0)
.map((args1) => {
    return doSomething(args1) ? "a" : "b"
})
.map((args2) => {
    return doSomething2(args2) ? true : false
})

The first map will know that the type of args1 is Number but the second one wont know that the type of args2 is string . And, as expected, subsequent chained functions wont know the types of their respective arguments. With what should unknown be replaced with so that every chained function figures out the type of its arguments based on the return type of the previously chained function?

You need to use a generic type parameter to refer to whatever the return type of the innerFunction is, so that you can then provide that type to TS when you recursively refer to myChainer .

Here is what that would look like:

function myChainer<T>(args:T){
    return {
       map<U>(innerFuction:(payload: T) => U) {
           return myChainer<U>(innerFuction(args))
       }
    }
}

Here you have:


function myChainer<T>(args: T) {
    return {
        map: <R,>(innerFuction: (payload: T) => R) => {
            return myChainer(innerFuction(args))
        }
    }
}

const foo = (arg: number) => arg.toString()
const bar = (arg: string) => Promise.resolve(parseInt(arg, 10))
const baz = (arg: Promise<number>) => arg


const result = myChainer(0)
    .map(arg => foo(arg)) // arg -> number
    .map(arg => bar(arg)) // arg -> string
    .map(arg => baz(arg)) // arg -> Promise<number>
    .map(arg => foo(arg)) // expected error

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM