type userType<T> = {
  id: number;
  firstName: string;
  lastName: string;
  age: T;
  job: string;
  address?: string;
  fullName?: string;
  result?: string;
};

type fnTypes = [
  fullName: (user: userType<string | number>) => userType<string | number>,
  addAddress: (user: userType<string | number>) => userType<string | number>,
  message: (user: userType<string | number>) => userType<string | number>
];

export default function TestTwo() {
  const user: userType<number | string> = {
    id: 1,
    firstName: "Gildong",
    lastName: "Hong",
    age: 29,
    job: "",
  };
  const fullName = (
    user: userType<string | number>
  ): userType<string | number> => {
    return {
      ...user,
      fullName: `${user.firstName} ${user.lastName}`,
    };
  };
  const addAddress = (
    user: userType<string | number>
  ): userType<string | number> => {
    return {
      ...user,
      address: "Seoul",
    };
  };
  const message = (
    user: userType<string | number>
  ): userType<string | number> => {
    return {
      ...user,
      result: `fullname: ${user.fullName} age: ${user.age} address: ${user.address}`,
    };
  };
  const compose =
    (...fn: fnTypes) =>
    (user: userType<string | number>) => {
      return fn.reduce((acc, fn) => fn(acc), user);
    };
  const result = compose(fullName, addAddress, message)(user);
  return (
    <div>
      <h1>{result.result}</h1>
    </div>
  );
}