Skip to content

Instantly share code, notes, and snippets.

@kino6052
Last active December 19, 2022 06:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kino6052/a8513973f7595b47ef9df49a8c7017d0 to your computer and use it in GitHub Desktop.
Save kino6052/a8513973f7595b47ef9df49a8c7017d0 to your computer and use it in GitHub Desktop.
const decorateWithNumber = <T>(p: T): T & { num: number } => ({ ...p, num: 10 });
const decorateWithBoolean = <T>(p: T): T & { bool: boolean } => ({ ...p, bool: true });
const decorateWithString = <T>(p: T): T & { str: string } => ({ ...p, str: 'string' });
const removeNumberDecoration = <T>({ num, ...rest }: T & { num?: number }): Omit<T, "num"> => ({ ...rest });
const functions = [decorateWithBoolean, decorateWithNumber, decorateWithString, removeNumberDecoration] as const;
function pipe<A, B>(f1: (a: A) => B): (a: A) => B;
function pipe<A, B, C>(f1: (a: A) => B, f2: (a: B) => C): (a: A) => C;
function pipe<A, B, C, D>(
f1: (a: A) => B,
f2: (a: B) => C,
f3: (a: C) => D
): (a: A) => D;
function pipe<A, B, C, D, E>(
f1: (a: A) => B,
f2: (a: B) => C,
f3: (a: C) => D,
f4: (a: D) => E
): (a: A) => E;
function pipe(...fn) {
return () => {};
}
type TReverse<T, R extends readonly any[] = []> = T extends readonly [
a: infer A,
...rest: infer _R
]
? TReverse<_R, [A, ...R]>
: R;
function compose<T extends readonly any[]>(fns: T) {
const r = [...fns].reverse() as TReverse<T>;
// @ts-ignore
return pipe(...r);
}
const TypeInferenceHelper = (args: typeof functions, arg: { test: 2 }) =>
pipe(...(args as TReverse<typeof args>))(arg);
type TComposedType = ReturnType<typeof TypeInferenceHelper>;
const result = compose(functions)({ test: 1 }) as TComposedType;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment