Skip to main content

Readonly 2

实现一个通用MyReadonly2 <T, K> ,它带有两种类型的参数 TK

// 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

/**
* 思路:
* 定义 K 是 T 的属性 并且赋予默认值
* 调用 MyOmit 过滤属性
* 使用 只读选择器 MyPick
*/

type MyExclude<T, U> = T extends U ? never : T;

type MyOmit<T, K extends keyof T> = {
[Key in MyExclude<keyof T, K>]: T[Key];
};

type MyPick<T, K extends keyof T> = {
[Key in K]: T[Key];
};

type MyReadonly2<T, K extends keyof T = keyof T> = MyOmit<T, K> &
Readonly<MyPick<T, K>>;