00009-medium-deep-readonly

Back

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

想知道是否有直接以T[K]而不是以keyof T[K]来作为递归判断条件的写法

Solution by Barrenboat #37270

type DeepReadonly<T> = {
  readonly [P in keyof T]: keyof T[P] extends never ? T[P] : DeepReadonly<T[P]>;
};
  1. readonly 的值 T[P],要判断是否还是个对象
  2. keyof T[P] extends never 不是对象返回 T[P],是对象则递归

Solution by djdidi #37144

type DeepReadonly<T> = {
  // If `keyof T[P] extends never`, that is to say `T[P]` is not an nesting object
  // So we return itself, or we return recursively DeepReadonly
  // This also support distribution of union type
  readonly [P in keyof T]: keyof T[P] extends never ? T[P] : DeepReadonly<T[P]>
} 

Solution by lumirelle #37103

type IsObject<T> = T extends Record<any, any> ? (T extends Function ? false: true) : false; 

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

Solution by ImSingee #37037

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

Solution by Divcutu #37033

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

Solution by 359Steve #37027

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

Solution by AlexBraunMagic #36906

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

Solution by qileioscar #36882

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

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<DeepReadonly<X1>, Expected1>>,
  Expect<Equal<DeepReadonly<X2>, Expected2>>,
]

type X1 = {
  a: () => 22
  b: string
  c: {
    d: boolean
    e: {
      g: {
        h: {
          i: true
          j: 'string'
        }
        k: 'hello'
      }
      l: [
        'hi',
        {
          m: ['hey']
        },
      ]
    }
  }
}

type X2 = { a: string } | { b: number }

type Expected1 = {
  readonly a: () => 22
  readonly b: string
  readonly c: {
    readonly d: boolean
    readonly e: {
      readonly g: {
        readonly h: {
          readonly i: true
          readonly j: 'string'
        }
        readonly k: 'hello'
      }
      readonly l: readonly [
        'hi',
        {
          readonly m: readonly ['hey']
        },
      ]
    }
  }
}

type Expected2 = { readonly a: string } | { readonly b: number }

Solution by AnastasiaSv #36881

type SetBasicType<T, U = T> = T extends T 
  ? [U] extends [T] 
    ? T 
    : DeepReadonly<T>
  : never;

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

Solution by kongwy229 #36814

// 여기 풀이를 입력하세요
type DeepReadonly<T> = T extends Function 
  ? T 
  : T extends {}
    ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
    : T

Solution by seungdeok #36710

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

Solution by ChemieAi #36562

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

Solution by byalashhab #36454

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

Solution by tac-tac-go #36452

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