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]>;
};
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
// 你的答案
type DeepReadonly
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