09775-hard-capitalize-nest-object-keys

Back

type CapitalizeNestObjectKeys<T> = T extends any[]
  ? {
      [P in keyof T]: CapitalizeNestObjectKeys<T[P]>;
    }
  : {
      [P in keyof T as Capitalize<P & string>]: T[P] extends any[]
        ? CapitalizeNestObjectKeys<T[P]>
        : T[P] extends object
        ? CapitalizeNestObjectKeys<T[P]>
        : T[P];
    };

Solution by Vampirelee #32691

type CapitalizeNestObjectKeys<T> = T extends any[]
  ? { [K in keyof T]: CapitalizeNestObjectKeys<T[K]> }
  : keyof T extends never
  ? T
  : { [K in keyof T as Capitalize<K & string>]: CapitalizeNestObjectKeys<T[K]> }; 

Solution by vangie #32243

type CapitalizeNestObjectKeys<T extends { [key: string]: any }> = {
  [K in keyof T as K extends string ? Capitalize<K> : K]: T[K] extends any[]
    ? HandleArray<T[K]>
    : T[K] extends { [key: string]: any }
    ? CapitalizeNestObjectKeys<T[K]>
    : T[K];
};

type HandleArray<T extends any[]> = T extends [infer F, ...infer R]
  ? F extends { [key: string]: any }
    ? [CapitalizeNestObjectKeys<F>, ...HandleArray<R>]
    : [F, ...HandleArray<R>]
  : T;

Solution by moonpoet #31471

type CapitalizeNestObjectKeys<T> = T extends unknown[] ? {
  [K in keyof T]: T[K] extends object ? CapitalizeNestObjectKeys<T[K]> : T[K]
} : {
  [K in keyof T as Capitalize<`${K & string}`>]: T[K] extends object ? CapitalizeNestObjectKeys<T[K]> : T[K]
}

Solution by dreamluo-plus #30786

// your answers
type ArrayCapitalizeNestObjectKeys <T extends any[]> = { [K in keyof T]: CapitalizeNestObjectKeys<T[K]> }
type CapitalizeNestObjectKeys<T> = { [K in keyof T as K extends string ? Capitalize<K> : never]: T[K] extends any[] ? ArrayCapitalizeNestObjectKeys<T[K]> : T[K] }

Solution by AAA611 #28899

type CapitalizeNestObjectKeys<T extends object> =
  T extends [infer F extends object, ...infer R] ?
  //ζ•°η»„ιεŽ†
  [
    CapitalizeNestObjectKeys<F>,
    ...(R extends [] ? [] : CapitalizeNestObjectKeys<R> extends any[] ? CapitalizeNestObjectKeys<R> : never)
  ] :
  //η»“ζž„δ½“
  { [P in keyof T as P extends string ? Capitalize<P> : P]: T[P] extends object ? CapitalizeNestObjectKeys<T[P]> : T[P] };

// old way
// ForEach version
// type TypeFuncMap<T = any> = {
//   CapitalizeNestObjectKeys: T extends object ? CapitalizeNestObjectKeys<T> : T;
// };
// type ForEach<T extends any[], FN extends keyof TypeFuncMap> = T extends [infer F, ...infer R] ? [TypeFuncMap<F>[FN], ...ForEach<R, FN>] : [];

// type CapitalizeNestObjectKeys<T extends object> = { [P in keyof T as P extends string ? Capitalize<P> : P]:
//   T[P] extends any[] ? ForEach<T[P], `CapitalizeNestObjectKeys`>
//   : T[P] extends object ? CapitalizeNestObjectKeys<T[P]> : T[P] };

Solution by E-uler #25130

type CapitalizeObjectKeysInArray<T extends {}[]> = T extends [infer First extends {}, ...infer Rest extends {}[]]
? [{
    [Key in keyof First as Key extends string ? Capitalize<Key> : Key]: First[Key]
  }, ...CapitalizeObjectKeysInArray<Rest>]
: []

type CapitalizeNestObjectKeys<T> = {
  [Key in keyof T as Key extends string ? Capitalize<Key> : Key]: T[Key] extends {}[]
    ? CapitalizeObjectKeysInArray<T[Key]>
    : T[Key]
}

Solution by NeylonR #24601

// 参考ζ₯ΌδΈ‹
type CapitalizeObjectKeys<T> = {
  [K in keyof T as  K extends string ? Capitalize<K> : K ]:CapitalizeNestObjectKeys<T[K]>
}

type CapitalizeObjectTuple<T extends any[]> = 
T extends [infer F,...infer R] 
?[CapitalizeObjectKeys<F>,...CapitalizeObjectTuple<R>] 
:[]

type CapitalizeNestObjectKeys<T> = 
  T extends any[]
  ? CapitalizeObjectTuple<T>
  : CapitalizeObjectKeys<T>

Solution by snakeUni #24120

// your answers
type CapitalizeObjectKeys<T> = {
  [K in keyof T as  K extends string ? Capitalize<K> : K ]:CapitalizeNestObjectKeys<T[K]>
}

type CapitalizeObjectTuple<T extends any[]> = 
T extends [infer F,...infer R] 
?[CapitalizeObjectKeys<F>,...CapitalizeObjectTuple<R>] 
:[]

type CapitalizeNestObjectKeys<T> = 
  T extends any[]
  ? CapitalizeObjectTuple<T>
  : CapitalizeObjectKeys<T>

Solution by jxhhdx #24056

type CapitalizeObjectKeys<T> = {
  [K in keyof T as  K extends string ? Capitalize<K> : K ]:CapitalizeNestObjectKeys<T[K]>
}

type CapitalizeObjectTuple<T extends any[]> = 
T extends [infer F,...infer R] 
?[CapitalizeObjectKeys<F>,...CapitalizeObjectTuple<R>] 
:[]

type CapitalizeNestObjectKeys<T> = 
  T extends any[]
  ? CapitalizeObjectTuple<T>
  : CapitalizeObjectKeys<T>

Solution by TKBnice #23594

type CapitalizeNestObjectKeys<T> =
  T extends unknown[]
    ? {
      [Key in keyof T]: CapitalizeNestObjectKeys<T[Key]>
    } : {
      [Key in keyof T as Key extends string ? Capitalize<Key> : never]: CapitalizeNestObjectKeys<T[Key]>
    }

Solution by drylint #22998

type CapitalizeNestObjectKeys<T> = T extends unknown[] ? {
  [K in keyof T]: CapitalizeNestObjectKeys<T[K]>
} : T extends object ? {
  [K in keyof T as K extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : never]: CapitalizeNestObjectKeys<T[K]>
} : T

Playground

Solution by teamchong #22542

// your answers
type CapitalizeNestObjetKeysInArray<T extends any[]> = T extends [
  infer F,
  ...infer R
]
  ? [CapitalizeNestObjectKeys<F>, ...CapitalizeNestObjetKeysInArray<R>]
  : [];
type CapitalizeNestObjectKeys<T> = T extends Record<PropertyKey, unknown>
  ? {
      [P in keyof T as P extends string
        ? Capitalize<Lowercase<P>>
        : P]: CapitalizeNestObjectKeys<T[P]>;
    }
  : T extends any[]
  ? CapitalizeNestObjetKeysInArray<T>
  : T;

Solution by acwink #22152

// your answers
type CapitalizeNestObjectKeys<T> = T extends readonly any[]
  ? {
      [K in keyof T]: CapitalizeNestObjectKeys<T[K]>;
    }
  : T extends Record<keyof any, any>
  ? {
      [K in keyof T as Capitalize<K & string>]: CapitalizeNestObjectKeys<T[K]>;
    }
  : T;

Solution by YqxLzx #22142

type CapitalizeNestObjectKeys<T> = 
  T extends Record<string, unknown>
  ? {
      [P in keyof T as P extends string ? Capitalize<P> : P]: CapitalizeNestObjectKeys<T[P]>
    }
  : T extends [infer First extends Record<string, unknown>, ...infer Rest]
    ? [CapitalizeNestObjectKeys<First>, ...CapitalizeNestObjectKeys<Rest>]
    : T

playground

Key points:

  1. handle object recursively
  2. handle array recursively
  3. retain T if it's not object or array

Solution by zhaoyao91 #22039

type DeepArrayToCapitalizeNestObjectKeys<T extends Array<any>> = 
T extends [infer A,...infer B] ?
[CapitalizeNestObjectKeys<A>,...DeepArrayToCapitalizeNestObjectKeys<B>]:[];

type CapitalizeNestObjectKeys<T> = {
  [P in keyof T as  Capitalize<P&string>]:T[P] extends Record<string,any> ? 
    T[P] extends Array<any> ? 
    DeepArrayToCapitalizeNestObjectKeys<T[P]>
    : CapitalizeNestObjectKeys<T[P]>:T[P];
}

Solution by so11y #21333

type CapitalizeNestObjectKeys<T> =
  T extends [ infer F, ...infer Rest ]
    ? Rest extends []
      ? [ CapitalizeNestObjectKeys<F> ]
      : [ CapitalizeNestObjectKeys<F>, ...(CapitalizeNestObjectKeys<Rest> extends unknown[] ? CapitalizeNestObjectKeys<Rest> : never) ]
    : T extends object
      ? {
        [P in keyof T as P extends `${ infer F }${ infer Rest }` ? `${ Capitalize<F> }${ Rest }` : never]: CapitalizeNestObjectKeys<T[P]>
      }
      : T

Solution by lvjiaxuan #20769

type CapitalizeNestObjectKeys<T> =
  T extends any[]
    ? T extends [infer F, ...infer R]
      ? [CapitalizeNestObjectKeys<F>, ...CapitalizeNestObjectKeys<R>]
      : []
    : T extends object
      ? { [K in keyof T as K extends string ? Capitalize<K> : never]: CapitalizeNestObjectKeys<T[K]> }
      : T

Solution by xiexuan-star #20126

type CapitalizeNestObjectKeys<T> = T extends [infer A, ...infer B]
  ? [CapitalizeNestObjectKeys<A>, ...CapitalizeNestObjectKeys<B>]
  : T extends Record<any, unknown>
  ? {
      [K in keyof T as K extends string | number
        ? Capitalize<`${K}`>
        : K]: T[K] extends object ? CapitalizeNestObjectKeys<T[K]> : T[K]
    }
  : T

Solution by theoolee #19808

// your answers
type Capital<T extends string> = T extends `${infer R}${infer U}`
                                    ? `${Uppercase<R>}${U}`
                                    : Uppercase<T>;


type CapitalList<T extends unknown[], Result extends unknown[] = []> = T extends  [infer R, ...infer U]
                                                ? CapitalList<U, [...Result, CapitalizeNestObjectKeys<R>]>
                                                : Result;

type CapitalizeNestObjectKeys<T extends unknown> = {
    [K in keyof T as (K extends string ? Capital<K> : K)]: T[K] extends Record<string, unknown>[]
                                                                    ? CapitalList<T[K]>
                                                                    : T[K] extends Record<string, any>
                                                                            ? CapitalizeNestObjectKeys<T[K]>
                                                                            : T[K];
}

Solution by jiaaoMario #18137

type CapitalizeNestObjectKeys<T extends object> = T extends [infer F, ...infer Rest] ? F extends object ? Rest extends [infer F2, ...infer Rest2] ? CapitalizeNestObjectKeys extends Array ? [CapitalizeNestObjectKeys, ...CapitalizeNestObjectKeys] : never : [CapitalizeNestObjectKeys] : never : { [P in keyof T as P extends string ? Uppercase

: never]: T[P] extends [infer F1, ...infer Rest1] ? CapitalizeNestObjectKeys<T[P]> : T[P] };

Solution by my5201314zwl #17168


type CapitalizeNestObjectKeys<T> = T extends readonly any[]
  ? {
      [K in keyof T]: CapitalizeNestObjectKeys<T[K]>;
    }
  : T extends Record<keyof any, any>
  ? {
      [K in keyof T as Capitalize<K & string>]: CapitalizeNestObjectKeys<T[K]>;
    }
  : T;

Solution by jiangshanmeta #16801

// your answers

type EachCapitalize<T extends unknown[]> = T extends [infer F, ...infer R]
  ? [CapitalizeNestObjectKeys<F>, ...EachCapitalize<R>]
  : []

type CapitalizeNestObjectKeys<T> = {
  [K in keyof T as K extends string ? Capitalize<K> : never]: T[K] extends unknown[]
    ? EachCapitalize<T[K]>
    : T[K] extends Record<string, unknown>
      ? CapitalizeNestObjectKeys<T[K]>
      : T[K]
}

Solution by humandetail #16556

// your answers
type CapitalizeArray<T extends any[], Result extends any[] = []> = 
  T extends [infer F, ...infer R]
    ? CapitalizeArray<R, [...Result, CapitalizeNestObjectKeys<F>]>
    : Result


type CapitalizeNestObjectKeys<T> = 
  T extends Record<string, unknown>
    // use type assertion (as) for Capitalization
    ? { [K in keyof T as K extends string ? Capitalize<K> : K] : T[K] extends any[] ? CapitalizeArray<T[K]> : T[K]}
    : T;

Solution by mook2-y2 #16470

// your answers
type CapitalizeNestObjectKeys<
    T > =
    T extends readonly object[]
    ? T extends [infer R extends object,...infer U extends object[]]
    ? [CapitalizeNestObjectKeys<R>,...CapitalizeNestObjectKeys<U>]
    : T 
    : T extends object
    ? {[J in keyof T as J extends string ? Capitalize<J> : J ] : CapitalizeNestObjectKeys<T[J]>}
    : T ;

Solution by justBadProgrammer #16075

type CapitalizeNestObjectKeys<T> = T extends any[]
  ? T extends [infer First, ...infer Rest]
    ? [CapitalizeNestObjectKeys<First>, ...CapitalizeNestObjectKeys<Rest>]
    : []
  : T extends object
  ? {
      [K in keyof T as K extends string ? Capitalize<K> : K]: T[K] extends object
        ? CapitalizeNestObjectKeys<T[K]>
        : T[K];
    }
  : T;

Solution by fabbrito #14575

type ArrayCapitalizeNestObjectKeys<T, U extends unknown[] = []> = T extends [infer F, ...infer Rest] ?
  ArrayCapitalizeNestObjectKeys<Rest, [...U, CapitalizeNestObjectKeys<F>]>
  : U

type CapitalizeNestObjectKeys<T> = {
  [K in keyof T as Capitalize<K & string>]: T[K] extends unknown[]?
    ArrayCapitalizeNestObjectKeys<T[K]>
    : T[K] extends Record<keyof any, any>
      ? CapitalizeNestObjectKeys<T[K]>
      : T[K]
}

Solution by XkSuperCool #14051

type CapitalizeArray<T extends Array<any>> =
  T extends [infer Head, ...infer Tail]
    ? [CapitalizeNestObjectKeys<Head>, ...CapitalizeArray<Tail>]
    : [];

type CapitalizeNestObjectKeys<T> =
  T extends number | string | boolean | undefined | null | symbol | bigint
    ? T
    : T extends Array<infer U>
      ? CapitalizeArray<T>
      : {
        [Key in keyof T as Capitalize<Key & string>]: CapitalizeNestObjectKeys<T[Key]>
      };

Solution by LeChatErrant #13336

// your answers
type CapitalizeArr<T,Res extends any[] = []> 
= T extends [infer Start,...infer End] 
? CapitalizeArr<End,[...Res,CapitalizeNestObjectKeys<Start> ]>
: Res

type CapitalizeNestObjectKeys<T>
 = T extends any[] 
? CapitalizeArr<T> 
: {
   [key in keyof T as Capitalize<key & string>]: CapitalizeNestObjectKeys<T[key]>
 }

Solution by EGyoung #12931

type CapitalizeNestObjectKeys<T> = {
  [key in keyof T as Capitalize<key & string>]: T[key] extends any[]
    ? Helper<T[key]>
    : T[key] extends object
      ? CapitalizeNestObjectKeys<T[key]>
      : T[key]
}

type Helper<T extends any[], R extends any[] = []> = T extends [infer F, ...infer Rest]
  ? F extends object
    ? F extends any[]
      ? Helper<Rest, [...R, Helper<F>]>
      : Helper<Rest, [...R, CapitalizeNestObjectKeys<F>]>
    : Helper<Rest, [...R, F]>
  : R

Solution by Sun79 #12685