// 你的答案
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
type DeepReadonly<T> =
T extends Function ? T :
T extends object ? { readonly [P in keyof T]: DeepReadonly<T[P]> } :
T
Solution by emen #34492
最初的答案:
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends Object ? DeepReadonly<T[K]> : T[K];
}
运行之后发现第一个案例无法通过,究其原因,对于案例中的函数,也会被默认为一个对象,由此遇到函数就会进行无限的递归调用。
//解法一:将函数作为基本类型一起归类为不需要递归调用
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends string | number | null | undefined | boolean | ((...args: any[]) => any) ? T[K] : DeepReadonly<T[K]>;
}
//解法二:由于函数不能再拆分成更加基本的类型,可以采用never类型进行判断
type DeepReadonly<T>={
readonly [K in keyof T]:T[K] extends never?T[K]:DeepReadonly<T[K]>
}
Solution by wxh-cyber #34476
type DeepReadonly<T> = T extends never ? T : {
readonly [P in keyof T]: DeepReadonly<T[P]>
}
Solution by ktim816 #34432
type DeepReadonly<T> = {
readonly [K in keyof T]: keyof T[K] extends never ? T[K] : DeepReadonly<T[K]>
}
Solution by rookie-luochao #34369
type DeepReadonly<T> = T extends any ?
keyof T extends never ? T : {
readonly [P in keyof T]: keyof T[P] extends never ? T[P]: DeepReadonly<T[P]>
}
: never;
Solution by leaderiop #34234
type DeepReadonly<T extends {}> = {
readonly [k in keyof T]: T[k] extends Function ? T[k] // 函数不需要递归
: T[k] extends {} ? DeepReadonly<T[k]> : T[k] // 如果是对象继续递归
}
Solution by quitone #34203
객체의 프로퍼티와 모든 하위 객체를 재귀적으로 읽기 전용으로 설정하는 제네릭 DeepReadonly<T>
를 구현하세요.
이 챌린지에서는 타입 파라미터 T
를 객체 타입으로 제한하고 있습니다. 객체뿐만 아니라 배열, 함수, 클래스 등 가능한 다양한 형태의 타입 파라미터를 사용하도록 도전해 보세요.
예시:
type X = {
x: {
a: 1;
b: "hi";
};
y: "hey";
};
type Expected = {
readonly x: {
readonly a: 1;
readonly b: "hi";
};
readonly y: "hey";
};
type Todo = DeepReadonly<X>; // should be same as `Expected`
type DeepReadonly<T> = {
readonly [key in keyof T]: T[key] extends object
? DeepReadonly<T[key]>
: T[key];
};
type Y1 = {
readonly a: DeepReadonly<() => 22>;
readonly b: string;
readonly c: DeepReadonly<{
d: boolean;
e: {
g: {
h: {
i: true;
j: "string";
다음과 작성했지만 예외 케이스를 통과하지 못했습니다. 제귀의 형태가 다소 이상하게 진행됨을 확인할 수 있었습니다. 저는 그 이유가 정확히 object를 찾아낼 방법이 필요하다고 생각했습니다. (원시타입이 아닌지)
keyof는 객체 타입의 모든 키를 유니언 타입으로 반환합니다. 예를 들어, 객체 타입이 { a: string, b: number }라면, keyof { a: string, b: number }는 'a' | 'b'가 됩니다.
never는 TypeScript에서 어떤 값도 가질 수 없는 타입을 의미합니다. 예를 들어, 함수가 항상 예외를 던지거나 끝나지 않는 경우 그 반환 타입은 never가 됩니다. 또한, 빈 객체의 키 타입을 keyof로 추출하려고 하면 never가 됩니다
type DeepReadonly<T> = {
readonly [K in keyof T]: keyof T[K] extends never ? T[K] : DeepReadonly<T[K]>;
};
type Y1 = {
readonly a: () => 22;
readonly b: string;
readonly c: DeepReadonly<{
d: boolean;
e: {
g: {
h: {
i: true;
j: "string";
/* _____________ 여기에 코드 입력 _____________ */
type DeepReadonly<T> = {
readonly [key in keyof T]: keyof T[key] extends never
? T[key]
: DeepReadonly<T[key]>;
};
/* _____________ 테스트 케이스 _____________ */
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 adultlee #34130
// 函数要单独考虑
type DeepReadonly<T extends object> = T extends any ? {
readonly [P in keyof T]: T[P] extends object ? (T[P] extends Function ? T[P] : DeepReadonly<T[P]>) : T[P]
} : never
Solution by ouzexi #33986
type Primitive = string | number | boolean | bigint | symbol | undefined | null
type Builtin = Primitive | Function | Date | Error | RegExp
type DeepReadonly<T> = T extends Builtin
? T
: T extends Map<infer K, infer V>
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends ReadonlyMap<infer K, infer V>
? ReadonlyMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends WeakMap<infer K, infer V>
? WeakMap<DeepReadonly<K>, DeepReadonly<V>>
: T extends Set<infer U>
? ReadonlySet<DeepReadonly<U>>
: T extends ReadonlySet<infer U>
? ReadonlySet<DeepReadonly<U>>
: T extends WeakSet<infer U>
? WeakSet<DeepReadonly<U>>
: T extends Promise<infer U>
? Promise<DeepReadonly<U>>
: T extends {}
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
: Readonly<T>
Solution by notsecret32 #33888
type DeepReadonly<T> = keyof T extends never ? T : {
readonly [K in keyof T]: DeepReadonly<T[K]>
}
Solution by Danny101201 #33808
type DeepReadonly<T> = {
readonly [P in keyof T]: keyof T[P] extends never
? T[P]
: DeepReadonly<T[P]>
}
Solution by laplace1009 #33714
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends object
? T[K] extends Function
? T[K]
: DeepReadonly<T[K]>
: T[K];
};
Solution by Alex-Nicalace #33668
// 你的答案
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends Function ? T[P] :DeepReadonly<T[P]>
}
Solution by heyuelan #33660
type DeepReadonly<T> = {
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};
Solution by OgabekYuldoshev #33584
type DeepReadonly<T> = {
readonly [Prop in keyof T]: T[Prop] extends (...args: any) => any
? T[Prop]
: T[Prop] extends object
? DeepReadonly<T[Prop]>
: T[Prop];
};```
Solution by Kolufs #33537
type DeepReadonly<T> = {
readonly [P in keyof T]: keyof T[P] extends never ? T[P] : DeepReadonly<T[P]>;
};
Solution by partiality #33344