728x90
문제
T
에서 K
프로퍼티만 읽기 전용으로 설정해 새로운 오브젝트 타입을 만드는 제네릭 MyReadonly2<T, K>
를 구현하세요. K
가 주어지지 않으면 단순히 Readonly<T>
처럼 모든 프로퍼티를 읽기 전용으로 설정해야 합니다.
interface Todo {
title: string
description: string
completed: boolean
}
const todo: MyReadonly2<Todo, 'title' | 'description'> = {
title: "Hey",
description: "foobar",
completed: false,
}
todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
todo.completed = true // OK
cases
type cases = [
Expect<Alike<MyReadonly2<Todo1>, Readonly<Todo1>>>,
Expect<Alike<MyReadonly2<Todo1, 'title' | 'description'>, Expected>>,
Expect<Alike<MyReadonly2<Todo2, 'title' | 'description'>, Expected>>,
]
// @ts-expect-error
type error = MyReadonly2<Todo1, 'title' | 'invalid'>
interface Todo1 {
title: string
description?: string
completed: boolean
}
interface Todo2 {
readonly title: string
description?: string
completed: boolean
}
interface Expected {
readonly title: string
readonly description?: string
completed: boolean
}
정답
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [key in K]: T[key]
} & {
[key in keyof T as key extends K ? never : key]: T[key]
}
풀이
조건
- K에 있는 항목들만 readonly로 변경한다.
- K가 없는 경우, 전부 readonly로 변경한다.
- K의 값은 T의 키에 포함된 값이어야 한다.
해설
우선 readonly
를 구현한다.
type MyReadonly2<T, K> = {
readonly [key in keyof T]: T[key]
}
K
에 있는 항목들을 readonly
로 변경하도록 수정한다.
type MyReadonly2<T, K> = {
readonly [key in key]: T[key]
}
K
이외의 나머지 항목들은 그대로 유지하는 로직을 추가한다.
type MyReadonly2<T, K> = {
readonly [key in key]: T[key]
} & {
[key in keyof T as key extends K ? never : key]: T[key]
}
K
가 없는 경우, 전부 readonly
처리하도록 수정한다.
type MyReadonly2<T, K = keyof T> = {
readonly [key in key]: T[key]
} & {
[key in keyof T as key extends K ? never : key]: T[key]
}
조건 3에 따라 K
의 입력에 제한을 둔다.
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [key in key]: T[key]
} & {
[key in keyof T as key extends K ? never : key]: T[key]
}
혹시 오류나 개선점이 있다면 댓글 부탁드립니다.
728x90
'FE > type-challenge' 카테고리의 다른 글
10. TupleToUnion (0) | 2023.09.04 |
---|---|
9. DeepReadonly (1) | 2023.09.02 |
3. Omit (0) | 2023.08.31 |
2. ReturnType (0) | 2023.08.30 |
7544. ConstructTuple (0) | 2023.08.26 |