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号