Манипуляции с типами Typescript

Нужна ваша помощь с манипуляциями типов Есть вот такой базовый интерфейс ( не доработанный )

interface IFormData<Inputs> {
    data: Inputs;
    transformData?: (data: Inputs) => <какой то результат преобразования данных>;
    getData?: (values: Inputs или результат работы функции transformData) => ...
}

Замечу, transformData может передаваться функция а может и нет, это опциальный параметр.

Как реализовать, чтобы при передаче функции transformData, у нас менялся тип в getData(values: ...)

Функция для интерфейса

function transformer<T>({
    getData,
    transformData,
    data
}: IFormData<T>) {
    if(getData) {
        if(transformData) {
            getData(transformData(data)) // something to do
        } else {
            getData(data)
        }
    }
}

примеры получения данных

Случай с transformData

const {getData} = transformer({
    data: {
        first_name: "",
        last_name: "string",
        age: 34
    },
    transformData: (data) => {
        return {
            fullname: data.first_name + " " + data.last_name,
            age: data.age
        }
    },
    getData(values) {
        в этой функции тип values = {
            fullname: string; 
            age: number
        }
    }
})

Случай без transformData

const {getData} = transformer({
    data: {
        first_name: "",
        last_name: "string",
        age: 34
    },
    getData(values) {
        в этой функции тип values = {
            first_name: string;
            last_name: string 
            age: number
        }
    }
})

Минимальный код


Ответы (1 шт):

Автор решения: DAYMERE

Нашел решение. Кому интересно

interface IFormData<I, R> {
    data: I;
    transformData?: (data: I) => R,
    getData?: (values: R) => any; // who knows
}

function transformer<I, R = I>({
    getData,
    transformData,
    data
}: IFormData<I, R>): void;

function transformer({ getData, transformData, data }: any) {
    if (getData) {
        if (transformData) {
            getData(transformData(data)) // something to do
        } else {
            getData(data) // something to do
        }
    }
}

namespace One {
    transformer({
        data: {
            first_name: "",
            last_name: "string",
            age: 34
        },
        transformData: (data) => {
            return {
                fullname: data.first_name + " " + data.last_name,
                age: data.age
            }
        },
        getData(values) {
            //  ^?

        }
    })
}

namespace Two {

    transformer({
        data: {
            first_name: "John",
            last_name: "Makeev",
            age: 34
        },
        getData(values) {
            //  ^?
        }
    })

}
→ Ссылка