I want a function that returns an object. The said function can also take n amount of functions as args, and use them to modify the object before returning it. My problem is that after doing the change I don't get the correct typescript type.
In this example I have the main function getUser
and two modifier functions modStatus
, modAge
. When I call getUser
with both modifiers I want to get UserModStatus & UserModAge & User
as a return type
type User = {
name: string;
};
type UserModAge = {
age: number;
};
type UserModStatus = {
status: "single" | "married";
};
type Mod<EXTRA> = <BASE>(user: BASE) => EXTRA & BASE;
const getUser = <T>(...mods: Mod<T>[]) => {
const user: User = {
name: "John",
};
return mods.reduce((acc, mod) => mod(acc), user);
};
const modAge: Mod<UserModAge> = (user) => {
return { ...user, age: 21 };
};
const modStatus: Mod<UserModStatus> = (user) => {
return { ...user, status: "married" };
};
const res = getUser(modStatus, modAge); // const res: User
However the return type is just the initial "User" type.
If I use static args it works fine
const getUser = <T, V>(mod1: Mod<T>, mod2: Mod<V>) => {
const user: User = {
name: "John",
};
return mod1(mod2(user));
};
const res = getUser(modStatus, modAge); // const res: UserModStatus & UserModAge & User
but I need them to be dynamic. Is there a way to achieve that?
The desired result is to get the correct type when applying different modifiers
const res = getUser();
// const res: User
const res = getUser(modAge);
// const res: UserModAge & User
const res = getUser(modStatus);
// const res: UserModStatus & User
const res = getUser(modStatus, modAge);
// const res: UserModStatus & UserModAge & User