00009-medium-deep-readonly

Back

type DeepReadonly<T> = 
T extends (...args:any[]) => any
? T
: T extends readonly any[]
  ? {readonly[U in keyof T] : DeepReadonly<T[U]>}
  : T extends object
    ? {readonly [K in keyof T] : DeepReadonly<T[K]>}
    :T

Solution by gakki-san #36373

type DeepReadonly = { readonly [P in keyof T]: T[P] extends object ? T[P] extends Function ? T[P] : DeepReadonly<T[P]> :T[P] }

Solution by asylbekduldiev #36344

type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends Function | never ? T[P] : DeepReadonly<T[P]>;
}

Solution by xilisky #36329

type DeepReadonly = T extends (...args: any[]) => any ? T : T extends readonly any[] ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T;

Solution by Bogdahn-Ishenko #36204

type is_arr<T extends any[]> = T[number] extends any[] ?  is_arr<T[number]> : T[number] extends object ? DeepReadonly<T[number]> : T[number]  ;
type DeepReadonly<T extends object> = {
  readonly[P in keyof T] : T[P] extends string | Function | number | boolean 
  ? T[P] extends any[] ? is_arr<T[P]> : T[P] : T[P] extends object ? DeepReadonly<T[P]> : T[P]
}

Solution by 352623635 #36167

type ExpectedReadOnlyFunc<T> = {
  readonly [Key in keyof T]: T[Key] extends {[Key: string]: unknown;}
    ? {
      readonly [KeyChild in keyof T[Key]]: T[Key][KeyChild];
    }
    : T[Key];
}

Solution by dekguh #36088

type DeepReadonly<T> = { readonly [K in keyof T]: keyof T[K] extends never ? T[K] : DeepReadonly<T[K]> };

BTW, as for now, the recommended solution from here is failed on second case, because it breaks distributive conditioning in case of unions

Expect<Equal<DeepReadonly<X2>, Expected2>>,

Solution by karazyabko #36038

type DeepReadonly<T> = { readonly [K in keyof T]: keyof T[K] extends never ? T[K] : DeepReadonly<T[K]> };

BTW, as for now, the recommended solution from here is failed on second case, because it breaks distributive conditioning in case of unions

Expect<Equal<DeepReadonly<X2>, Expected2>>,

Solution by karazyabko #36020

// your answers
type DeepReadonly<T> = T extends Object
  ? {
      readonly [K in keyof T]: T[K] extends Function
        ? T[K]
        : DeepReadonly<T[K]>;
    }
  : T;

Solution by z-w-H #35982

type DeepReadonly<T> = { readonly [K in keyof T]: keyof T[K] extends never ? T[K] : DeepReadonly<T[K]>}

Solution by a-super-cat #35894

type DeepReadonly<T> = {
  readonly [key in keyof T]: keyof T[key] extends never
    ? T[key]
    : DeepReadonly<T[key]>;
};

Solution by RanungPark #35449

type DeepReadonly<T> = {
  readonly [K in keyof T]: keyof T[K] extends never ? T[K] : DeepReadonly<T[K]>
}

Solution by wendao-liu #35353

type DeepReadonly<T> = T extends unknown 
   ? keyof T extends never ? T: { readonly [k in keyof T]: DeepReadonly<T[k]> }
   : T

Solution by lxxorz #35340

// 你的答案

type DeepReadonly = { readonly [key in keyof T]: T[key] extends (...args: any[]) => any ? T[key] : T[key] extends object ? DeepReadonly<T[key]> : T[key] }

Solution by front-end-Dean #35313

type DeepReadonly<T extends Object> = T extends Record<string, any> ? {
  readonly [P in keyof T] : T[P] extends Record<string, any>  ?  T[P] extends Function ? T[P] :   DeepReadonly<T[P]> : T[P]
} : T

Solution by yujun96 #35285

type DeepReadonly<T> = {
	readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
}

Solution by ClarityOfMind #35274

// 你的答案
type DeepReadonly<T> = {
  readonly [Key in keyof T]: T[Key] extends Function ? T[Key] : T[Key] extends object ?  DeepReadonly<T[Key]> : T[Key]
}

/* type DeepReadonly<T> = T extends Function ? T : T extends object ? {
  readonly [Key in keyof T]: DeepReadonly<T[Key]>
} : T */

Solution by HoseaGuo #35160

handle non-object types

type DeepReadonly<T> = T extends Function
  ? T
  : T extends object
  ? {
      readonly [key in keyof T]: DeepReadonly<T[key]>;
    }
  : T;```

Solution by baixiaoyu2997 #35131

type DeepReadonly<T> = T extends object
  ? { readonly [P in keyof T]: DeepReadonly<T[P]> }
  : T;

Solution by raeyoung-kim #34998

type DeepReadonly<T> = {
  // readonly [key in keyof T]: T[key]
  readonly [key in keyof T]: keyof T[key] extends never ? T[key] : DeepReadonly<T[key]>
}

Solution by 56aiden90 #34920

type DeepReadonly<T> = keyof T extends never ? T : { readonly [key in keyof T]: DeepReadonly<T[key]> }

Solution by floatDreamWithSong #34873

type DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? T[P] extends Function ? T[P] : DeepReadonly<T[P]> : T[P] }

Solution by 2083335157 #34846

type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object 
      ? (isFunction<T[K]> extends true ? T[K] : DeepReadonly<T[K]>) 
      : T[K];
};

type isFunction<T> = T extends (...args: any[]) => any? true : false

Solution by lfz9527 #34829

type DeepReadonly<T> = T extends Function 
  ? T 
  : T extends never 
    ? T 
    : { readonly [Key in keyof T]: DeepReadonly<T[Key]> }

Solution by eunsukimme #34826

type DeepReadonly<T> = {readonly [P in keyof T]: T[P] extends (...args: any) => any? T[P] : T[P] extends object? DeepReadonly<T[P]> :T[P]}

Solution by SOL-MI #34801

// your answers
type DeepReadonly<T> = T extends (...args: any[]) => any
  ? T
  : T extends object
  ? { readonly [P in keyof T]: DeepReadonly<T[P]> }
  : T;

Solution by zeyuanHong0 #34782

type Base = {
  id: number
  title: string
  address: {
    street: string
    city: string
  }
}
type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
}

type DeepReadonlyBase = DeepReadonly<Base>

const todo: DeepReadonlyBase = {
  id: 1,
  title: 'Hello',
  address: {
    street: '123',
    city: 'world'
  }
}

Solution by semet #34642

Use recursive types. We should check T's recursive ending condition.


type DeepReadonly<T> = T extends symbol | Function ? T: {
  readonly [K in keyof T]: DeepReadonly<T[K]>;
}

Solution by dev-jaemin #34631

type DeepReadonly<T> = {
  readonly [P in keyof T]: 
    keyof T[P] extends never 
    ? T[P] 
    : DeepReadonly<T[P]>
}

Solution by binhdv155127 #34612

type DeepReadonly<T> = T extends object
  ? (
    T extends [ infer A, ...infer B ]
      ? readonly [ DeepReadonly<A>, ...DeepReadonly<B> ]
      : (
        T extends Function
          ? T
          : {
            readonly [P in keyof T]: DeepReadonly<T[P]>
          }
      )
  )
  : T

Solution by devshinthant #34561