8 - 对象部分属性只读
实现一个泛型MyReadonly2<T, K>
,它带有两种类型的参数T
和K
。
类型 K
指定 T
中要被设置为只读 (readonly) 的属性。如果未提供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
Solution
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in K]: T[P]
} & {
[P in keyof T as P extends K ? never : P]: T[P]
}
readonly [P in K]: T[P]
: 遍历K
, 将给定的属性变为readonly
[P in keyof T as P extends K ? never : P]: T[P]
: 分别两部分 (P in keyof T) as (P extends K ? never : P)P in keyof T
: 遍历T
中的属性名P extends K ? never : P
:P
是K
的子集,说明需要设置为readonly
, 由于前面已经设置过了,只需返回never
, 不是K
的子集,则返回P