type IsOject<T extends unknown> =
[T] extends [object] ?
[T] extends [
Function |
any[] |
Date |
RegExp |
WeakMap<any, any> |
WeakSet<any> |
Map<any, any> |
Set<any> |
Error
] ? false : true
: false;
type DeepReadOnly<T> = IsOject<T> extends true
? { readonly [K in keyof T]: DeepReadOnly<T[K]> }
: T;
// Test cases
type A = DeepReadOnly<{
a: {
b: {
c: string;
};
d: number[];
e: () => void;
f: Date;
g: {
h: {
i: boolean;
};
};
};
}>;
// Expected:
// type A = {
// readonly a: {
// readonly b: {
// readonly c: string;
// };
// readonly d: readonly number[];
// readonly e: () => void;
// readonly f: Date;
// readonly g: {
// readonly h: {
// readonly i: boolean;
// };
// };
// };
// }
Solution by w3Scribe #37605
// your answers
type DeepReadonly
}
Solution by PAVANT009 #37599
type DeepReadonly<T> = T extends Function
? T
: {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
Solution by eel-brah #37496
type DeepReadonly<T> = {
readonly [K in keyof T]:keyof T[K] extends never ?T[K]: DeepReadonly<T[K]>
}
Solution by Barrenboat #37270
type DeepReadonly<T> = {
readonly [P in keyof T]: keyof T[P] extends never ? T[P] : DeepReadonly<T[P]>;
};
T[P],要判断是否还是个对象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
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
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
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