跳到主要内容

Readonly2

介绍

实现MyReadonly2<T,K>, 其接收两个类型参数TK

K指定T属性集合中应该设置为只读. 当K没有提供, 应该让所有属性只读,就像通常的Readonly<T>

例如

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
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
View on GitHub

start point

ts
/* _____________ Your Code Here _____________ */
 
type MyReadonly2<T, K> = any
 
/* _____________ Test Cases _____________ */
type cases = [
Expect<Alike<MyReadonly2<Todo1, 'title' | 'description'>, Expected>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Alike<MyReadonly2<Todo2, 'title' | 'description'>, Expected>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
]
 
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
}
 
ts
/* _____________ Your Code Here _____________ */
 
type MyReadonly2<T, K> = any
 
/* _____________ Test Cases _____________ */
type cases = [
Expect<Alike<MyReadonly2<Todo1, 'title' | 'description'>, Expected>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Alike<MyReadonly2<Todo2, 'title' | 'description'>, Expected>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
]
 
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
}
 
take the challenge

my solutions

Spoiler warning // Click to reveal answer
ts
//方案1
 
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in keyof T as P extends K ? P : never]: T[P]
} & {
[P in keyof T as P extends K ? never : P]: T[P]
}
 
 
ts
//方案1
 
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in keyof T as P extends K ? P : never]: T[P]
} & {
[P in keyof T as P extends K ? never : P]: T[P]
}
 
 
ts
//方案2 方案1的变种
 
type Pick2<T, K extends keyof T> = {
readonly [P in keyof T as P extends K ? P : never]: T[P]
}
 
type Omit2<T, K extends keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P]
}
 
type MyReadonly2<T, K extends keyof T = keyof T> = Pick2<T, K> & Omit2<T, K>
 
ts
//方案2 方案1的变种
 
type Pick2<T, K extends keyof T> = {
readonly [P in keyof T as P extends K ? P : never]: T[P]
}
 
type Omit2<T, K extends keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P]
}
 
type MyReadonly2<T, K extends keyof T = keyof T> = Pick2<T, K> & Omit2<T, K>
 
ts
//方案3 most popular
 
type MyReadonly2<T, K extends keyof T = keyof T > = Omit<T,K> &
Readonly<Pick<T,K>>
 
ts
//方案3 most popular
 
type MyReadonly2<T, K extends keyof T = keyof T > = Omit<T,K> &
Readonly<Pick<T,K>>
 
view more solutions