Вывод типов параметров в цепочке функций

#typescript #functional-programming

#typescript #функциональное программирование

Вопрос:

Я пытаюсь создать самодельную цепочку сопоставления функций. Дело в том, что я хочу убедиться, что ввод текста остается согласованным во всей цепочке сопоставления. Моя проблема в том, что я не знаю, как писать f(x:T) => U

Для правильного примера того, что я пытаюсь сделать:

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

 

Теперь, если я запущу

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

Первый map будет знать, что тип args1 is Number , но второй не будет знать, что тип args2 is string . И, как и ожидалось, последующие связанные функции не будут знать типы своих соответствующих аргументов. Чем следует unknown заменить, чтобы каждая цепная функция определяла тип своих аргументов на основе возвращаемого типа ранее цепной функции?

Комментарии:

1. Пожалуйста, поделитесь воспроизводимым кодом

2. Второй общий тип, U, нигде не задан. Это должно быть в методе map, поэтому внутренняя функция может быть T => U: typescriptlang.org/play ? #code/ .

3. @jonrsharpe Где должно U быть установлено? Я бы хотел установить его где myChainer -нибудь, чтобы все новые отображаемые функции могли определять типы параметров из возвращаемого значения предыдущей функции

Ответ №1:

Вам нужно использовать параметр общего типа для ссылки на любой возвращаемый тип innerFunction is, чтобы затем вы могли предоставить этот тип TS при рекурсивной ссылке myChainer .

Вот как это будет выглядеть:

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

Ответ №2:

Здесь у вас есть:

 
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
 

Комментарии:

1. @GregL был быстрее)