27932-medium-mergeall

Back

type MergeAll<
  XS extends object[],
  U = XS[number],
  Keys extends PropertyKey = U extends U ? keyof U : never
> = {
  [K in Keys]: U extends U ? U[K & keyof U] : never
}

Playground

Solution by teamchong #33000

type MergeAll<XS, Acc extends object = NonNullable<unknown>> = XS extends [infer F, ...infer R]
  ? MergeAll<R, {
    [P in keyof F | keyof Acc]: P extends keyof Acc
                                  ? Acc[P] | F[keyof F & P]
                                  : F[keyof F & P]
  }>
  : Acc

Solution by keyurparalkar #32844

type MergeObject<M, N, O extends PropertyKey = keyof M | keyof N> = {
  [P in O]: M[P & keyof M] | N[P & keyof N];
};

type MergeAll<
  T extends any[],
  M extends Record<PropertyKey, any> = {}
> = T extends [infer L, ...infer R] ? MergeAll<R, MergeObject<L, M>> : M;

Solution by Vampirelee #32585

type MergeAll<XS, M = {}> = XS extends [infer X, ...infer R]
  ? MergeAll<
      R,
      {
        [K in keyof M | keyof X]: K extends keyof X
          ? K extends keyof M
            ? M[K] | X[K]
            : X[K]
          : M[K & keyof M];
      }
    >
  : M;

Solution by vangie #32202

type MergeAll<T extends any[], U extends object = {}> = T extends [
  infer F,
  ...infer R
]
  ? F extends object
    ? MergeAll<
        R,
        {
          [K in keyof F | keyof U]: K extends keyof U
            ? K extends keyof F
              ? F[K] | U[K]
              : U[K]
            : K extends keyof F
            ? F[K]
            : never;
        }
      >
    : MergeAll<R, U>
  : U;

Solution by moonpoet #31047

type Merge<T, U> = {[K in keyof T | keyof U]: (K extends keyof T ? T[K] : never) | (K extends keyof U ? U[K] : never)};

type MergeAll<XS extends any[]> =
  XS extends [infer O, ...infer X]
    ? Merge<O, MergeAll<X>>
    : {}

Solution by milletlovemouse #31004

type FlattenKeys<T extends {}[], U extends {} = {}> = T extends [infer F, ...infer Rest extends {}[]]
  ? FlattenKeys<
      Rest,
      {
        [key in keyof F | keyof U]: [];
      }
    >
  : U;

type Unionize<T> = T extends [infer F, ...infer Rest]
  ? unknown extends F
    ? Unionize<Rest>
    : F | Unionize<Rest>
  : never;

type MergeAll<T extends {}[], R extends Record<PropertyKey, any> = FlattenKeys<T>> = T extends [
  infer F extends Record<PropertyKey, any>,
  ...infer Rest extends {}[],
]
  ? MergeAll<
      Rest,
      {
        [key in keyof R]: [F[key], ...R[key]];
      }
    >
  : {
      [key in keyof R]: Unionize<R[key]>;
    };

Solution by leejaehyup #30928

type Merge<T,V> = {
    [Key in keyof T | keyof V] : Key extends keyof T 
                                    ? Key extends keyof V 
                                            ? T[Key] | V[Key] 
                                            : T[Key] 
                                    : V[Key];   
}

type MergeAll<XS,All = {}> = XS extends [infer First,...infer Rest] ? MergeAll<Rest,Merge<All,First>>: All;

Solution by idebbarh #30173

type MergeAll<T, S = {}> = T extends [infer F, ...infer Rest]
  ? MergeAll<Rest, Omit<{
    [P in Exclude<keyof S, keyof F>]: S[P]
  } & {
    [P in Exclude<keyof F, keyof S>]: F[P]
  } & {
    [P in Extract<keyof S, keyof F>]: S[P] | F[P]
  }, never>>
  : S

Solution by hesoso #30069

type MergeAll<
  XS extends object[],
  U = XS[number],
  Keys extends PropertyKey = U extends U ? keyof U : never
> = {
  [K in Keys]: U extends U ? U[K & keyof U] : never
}

Solution by Alexsey #29394

type Merge<T, M> = { [k in (keyof T) | (keyof M)]: k extends keyof T ? k extends keyof M ? T[k] | M[k] : T[k] : M[k]}
type MergeAll<T, R = {}> = T extends [infer I, ...infer Rest] ? MergeAll<Rest, Merge<R, I>> : R;

Solution by MrRENGE #29284

// your answers
type Merge<F, S> = {
  [K in keyof F | keyof S]: K extends keyof F ? K extends keyof S ? F[K] | S[K] : F[K] : K extends keyof S ? S[K] : never
}

type MergeAll<XS extends any[], Result extends object = {}> = XS extends [infer F, ...infer Rest] ? MergeAll<Rest, Merge<Result, F>> : Result;

Solution by suchangv #29277

type MergeAll<XS extends unknown[], Res = {}> = XS extends [
  infer Item,
  ...infer Rest
]
  ? MergeAll<
      Rest,
      Omit<
        Omit<Res, keyof Item> & {
          [K in keyof Item]: K extends keyof Res ? Res[K] | Item[K] : Item[K];
        },
        never
      >
    >
  : Res;

Solution by DoubleWoodLin #28919

ι€’ε½’ιεŽ†οΌŒθΏ›θ‘ŒεˆεΉΆοΌŒη”¨δΈ€δΈͺη©Ίε―Ήθ±‘ζ”Άι›†ζ‰€ζœ‰ηš„η»“ζžœ

type MergeAll<XS, P = {}> = XS extends [infer F, ...infer Rest] 
  ? MergeAll<Rest, Merge<P, F>>
  : P

type Merge<F, S> = {
  [P in keyof F | keyof S]: 
    P extends keyof S 
    ? P extends keyof F
      ? S[P] | F[P]
      : S[P]
    : P extends keyof F
      ? F[P]
      :never
}

Solution by linjunc #28601

type MergeObj<T extends object, U extends object> = { [P in (keyof T | keyof U)]:
  P extends keyof T ?
  T[P] | (P extends keyof U ? U[P] : never) :
  P extends keyof U ? U[P] : never };
type MergeAll<XS extends object[]> = XS extends [] ?
  {} :
  XS extends [infer F extends object, infer S extends object, ...infer R extends object[]] ? MergeAll<[MergeObj<F, S>, ...R]> : XS[0];

Solution by E-uler #28122

type Merge<A, B> = {
  [K in keyof A | keyof B]: K extends keyof A
    ? K extends keyof B
      ? A[K] | B[K]
      : A[K]
    : K extends keyof B
      ? B[K]
      : never
}

type MergeAll<T, R extends Record<string, any> = {}> = T extends [infer F, ...infer Rest]
  ? MergeAll<Rest, Merge<R, F>>
  : R

Solution by XkSuperCool #28013

type Merge<T,U> = {
  [K in (keyof T) | (keyof U)]: 
    K extends keyof T?
      K extends keyof U?
        T[K] | U[K]
        : T[K]
      : K extends keyof U? U[K]:never
}

type MergeAll<XS extends any[],R = {}> = 
XS extends [infer F,...infer Z]?
  MergeAll<Z, Merge<R,F>>:R

Solution by jiangshanmeta #27988

type MergeAll<XS extends object[], Res = {}> = 
XS extends [infer L, ...infer R extends object[]]
  ? MergeAll<R, Omit<Res, keyof L> & { 
      [p in keyof L]: p extends keyof Res ? L[p] | Res[p] : L[p] 
    }>
  : Omit<Res, never>;

Solution by omittee #27962

type MergeAll<XS, Prev = {}> = XS extends [infer First, ...infer Rest]
  ? MergeAll<Rest, Merge<Prev, First>>
  : Prev

type Merge<O1, O2> = {
  [K in (keyof O1 | keyof O2)]: PropOr<O1, K> | PropOr<O2, K>
}

type PropOr<Obj, Prop, Default = never> = Prop extends keyof Obj
  ? Obj[Prop]
  : Default

Solution by Sun79 #27956