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

Я пытаюсь сделать домашнюю цепочку сопоставления функций. Дело в том, что я хочу убедиться, что набор текста остается согласованным в цепочке отображения. Моя проблема в том, что я не умею писать 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 — это Number, а второй не будет знать, что тип args2 — это string. И, как и ожидалось, последующие связанные функции не будут знать типы своих соответствующих аргументов. На что следует заменить unknown, чтобы каждая цепочка функций определяла тип своих аргументов на основе возвращаемого типа ранее связанной функции?

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

captain-yossarian from Ukraine 14.12.2020 09:45

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

jonrsharpe 14.12.2020 09:47

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

Axel 14.12.2020 09:50
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
2
3
226
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

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

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


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

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

captain-yossarian from Ukraine 14.12.2020 10:12

Другие вопросы по теме