View on GitHub: https://tsch.js.org/8
*/
/* _____________ Your Code Here _____________ */
type MyReadonly2 View on GitHub: https://tsch.js.org/8
*/ /* _____________ Your Code Here _____________ */ type MyReadonly2<T, K> = any /* _____________ Test Cases _____________ */
import { Equal, Expect } from '@type-challenges/utils' type cases = [
Expect<Equal<MyReadonly2<Todo1>, Readonly<Todo1>>>,
Expect<Equal<MyReadonly2<Todo1, 'title' | 'description'>, Expected>>,
] interface Todo1 {
title: string
description?: string
completed: boolean
} interface Expected {
readonly title: string
readonly description?: string
completed: boolean
} /* _____________ Further Steps _____________ /
/ Share your solutions: https://tsch.js.org/8/answer
View solutions: https://tsch.js.org/8/solutions
More Challenges: https://tsch.js.org
*/ 그런데 그랫더니 두번째 제네릭 파라미터를 전달하지 않는 경우의 테스트가 성공되지 않았다. 그래서 처음에는 조건부로 타입을 리턴하려 했는데 잘 안되서 고민하다가 K 의 기본값을 추가했다!! 어느날 다른 답/*
8 - Readonly 2
-------
by Anthony Fu (@antfu) #medium #readonly #object-keys
### Question
Implement a generic `MyReadonly2<T, K>` which takes two type argument `T` and `K`.
`K` specify the set of properties if `T` that should set to Readonly. When `K` is not provided, it should make all properties readonly just like the normal `Readonly<T>`.
For example
```ts
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
두번째 제네릭으로 전달 받은 키만 readonly로 만들어야 한다.
교차 타입을 사용해야 될 것 같긴 했다. 그런데 그랬을 때 동작은 되지만 타입이 제대로 인식이 안되어서 Combine 이라는 타입을 만들어서 merge 하는 느낌으로 만들어 주었다.
```tsx
type Combine<T> = {
[k in keyof T]: T[k]
}
type MyReadonly2<T, K extends keyof T> = Combine<T & {
readonly [S in K]: T[S]
}>
type Combine<T> = {
[k in keyof T]: T[k]
}
type MyReadonly2<T, K extends keyof T = keyof T> = Combine<T & {
readonly [S in K]: T[S]
}>
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [key in K]: T[key];
} & {
[key in Exclude<keyof T, K>]: T[key]
}