实现 Omit
About 1 minTC-Medium
实现 Omit
题目
实现一个泛型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
解答
type MyOmit<T, K extends keyof T> =
{[P in keyof T as P extends K ? never: P] :T[P]}
as
可以用来重映射属性名。
例如,我们声明一个使每个字符串属性名大写的类型:
type UpperProps<T> = {
[P in keyof T as Uppercase<`${string & P}`>]: T[P]
}
interface Todo {
title: string
description: string
completed: boolean
}
type TodoUpper = UpperProps<Todo>
// { TITLE: string, DESCRIPTION: string, COMPLETED: boolean }
特别的,当属性名被重映射为 never
时,它会被过滤掉。
type MyOmit<T, K extends keyof T> =
{
[P in keyof T // 遍历 T 的所有属性
as // 重映射属性名
P extends K // 如果属性名在 K 中
? never // 过滤掉
: P // 否则保留原来的值
] : T[P] // 保留属性值
}