#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 был быстрее)