实现 Omit
题目
Github: Omit
不使用 Omit
实现 TypeScript
的 Omit<T, K>
泛型。
Omit
会创建一个省略 K
中字段的 T
对象。
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyOmit<Todo, 'description' | 'title'>
const todo: TodoPreview = {
completed: false,
}
解题思路
首先这里需要创建一个新的对象类型,但不指定健,因此这里需要使用 映射类型。
type MyOmit<T, K> = {
[P in keyof T]: T[P]
}
这里通过 keyof
遍历 T
中的所有键,然后将其映射到类型 P
,使其成为新对象类型的键,其值为 T[P]
。
在此基础上,还需要对 keyof T
进行过滤,排除 K
中的所有健。
这里可以使用 as
语法重新映射键类型,最后新对象的值为 原类型的相对应键的值类型。
答案
type MyOmit<T, K extends keyof T> = {
[Key in keyof T as Key extends K ? never : Key]: T[Key]
}
验证
type cases = [
Expect<Equal<Expected1, MyOmit<Todo, 'description'>>>,
Expect<Equal<Expected2, MyOmit<Todo, 'description' | 'completed'>>>,
Expect<Equal<Expected3, MyOmit<Todo1, 'description' | 'completed'>>>,
]
// @ts-expect-error
type error = MyOmit<Todo, 'description' | 'invalid'>
interface Todo {
title: string
description: string
completed: boolean
}
interface Todo1 {
readonly title: string
description: string
completed: boolean
}
interface Expected1 {
title: string
completed: boolean
}
interface Expected2 {
title: string
}
interface Expected3 {
readonly title: string
}