Typescript类型体操 - Readonly 2
题目
中文
实现一个通用MyReadonly2<T, K>,它带有两种类型的参数T和K。
K指定应设置为Readonly的T的属性集。如果未提供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
English
Implement a generic MyReadonly2<T, K> which takes two type argument T and K.
K specify the set of properties of 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
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
答案
解法一,引入第三个泛型参数O
type MyReadonly2<T, K extends keyof T = keyof T, O extends keyof T = keyof T> = { readonly [P in keyof T]: T[P] } & {
  [P in (O extends K ? never : O)]: T[P]
}
解法二,借助MyOmit MyExclude辅助
type MyExclude<T, K> = T extends K ? never : T;
type MyOmit<T, K extends keyof T> = { [P in MyExclude<keyof T, K> ]: T[P] }
type MyReadonly2<T, K extends keyof T = keyof T> = { readonly [P in keyof T]: T[P] } & MyOmit<T, K>
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号