跳到主要内容

Omit

介绍

实现内置的Omit<T,K>而不需要使用它.

通过从T中移除K属性来构建一个类型

For example

ts
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyOmit<Todo, 'description' | 'title'>
const todo: TodoPreview = {
completed: false,
}
ts
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyOmit<Todo, 'description' | 'title'>
const todo: TodoPreview = {
completed: false,
}
View on GitHub

起点

ts
/* _____________ Your Code Here _____________ */
type MyOmit<T, K> = any
 
/* _____________ Test Cases _____________ */
type cases = [
Expect<Equal<Expected1, MyOmit<Todo, 'description'>>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Expected2, MyOmit<Todo, 'description' | 'completed'>>>
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
]
 
interface Todo {
title: string
description: string
completed: boolean
}
 
interface Expected1 {
title: string
completed: boolean
}
 
interface Expected2 {
title: string
}
ts
/* _____________ Your Code Here _____________ */
type MyOmit<T, K> = any
 
/* _____________ Test Cases _____________ */
type cases = [
Expect<Equal<Expected1, MyOmit<Todo, 'description'>>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<Expected2, MyOmit<Todo, 'description' | 'completed'>>>
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
]
 
interface Todo {
title: string
description: string
completed: boolean
}
 
interface Expected1 {
title: string
completed: boolean
}
 
interface Expected2 {
title: string
}
take the challenge

解决方案

Spoiler warning // Click to reveal answer
ts
// 方法1
type MyOmit<T,K extends keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P]
}
ts
// 方法1
type MyOmit<T,K extends keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P]
}
ts
//方法2
/**
* 方法2会在第三个测试中失败, 在 keyof T 被传递给 Exclude2 的时候。在这个阶段,TypeScript 只是处理了属性名的字符串,而不是保留了完整的属性描述符。
*/
type Exclude2<T,K extends T> = T extends K ? never : T;
 
type MyOmit2<T,K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P]
}
 
ts
//方法2
/**
* 方法2会在第三个测试中失败, 在 keyof T 被传递给 Exclude2 的时候。在这个阶段,TypeScript 只是处理了属性名的字符串,而不是保留了完整的属性描述符。
*/
type Exclude2<T,K extends T> = T extends K ? never : T;
 
type MyOmit2<T,K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P]
}
 
ts
//方案2的正确版本
 
type Exclude3<T, K> = T extends K ? never : T;
 
type MyOmit3<T, K extends T> = {
[P in keyof T as Exclude3<P, K>]: T[P]
}
 
ts
//方案2的正确版本
 
type Exclude3<T, K> = T extends K ? never : T;
 
type MyOmit3<T, K extends T> = {
[P in keyof T as Exclude3<P, K>]: T[P]
}
 
view more solutions