Omit
介绍
实现内置的Omit<T,K>
而不需要使用它.
通过从T
中移除K
属性来构建一个类型
For example
ts
interface Todo {title: stringdescription: stringcompleted: boolean}type TodoPreview = MyOmit<Todo, 'description' | 'title'>const todo: TodoPreview = {completed: false,}
View on GitHubts
interface Todo {title: stringdescription: stringcompleted: boolean}type TodoPreview = MyOmit<Todo, 'description' | 'title'>const todo: TodoPreview = {completed: false,}
起点
ts
/* _____________ Your Code Here _____________ */typeMyOmit <T ,K > = any/* _____________ Test Cases _____________ */typecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.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'>>>]interfaceTodo {title : stringdescription : stringcompleted : boolean}interfaceExpected1 {title : stringcompleted : boolean}interfaceExpected2 {title : string}
take the challengets
/* _____________ Your Code Here _____________ */typeMyOmit <T ,K > = any/* _____________ Test Cases _____________ */typecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.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'>>>]interfaceTodo {title : stringdescription : stringcompleted : boolean}interfaceExpected1 {title : stringcompleted : boolean}interfaceExpected2 {title : string}
解决方案
Spoiler warning // Click to reveal answer
ts
// 方法1typeMyOmit <T ,K extends keyofT > = {[P in keyofT asP extendsK ? never :P ]:T [P ]}
ts
// 方法1typeMyOmit <T ,K extends keyofT > = {[P in keyofT asP extendsK ? never :P ]:T [P ]}
ts
//方法2/*** 方法2会在第三个测试中失败, 在 keyof T 被传递给 Exclude2 的时候。在这个阶段,TypeScript 只是处理了属性名的字符串,而不是保留了完整的属性描述符。*/typeExclude2 <T ,K extendsT > =T extendsK ? never :T ;typeMyOmit2 <T ,K extends keyofT > = {[P inExclude <keyofT ,K >]:T [P ]}
ts
//方法2/*** 方法2会在第三个测试中失败, 在 keyof T 被传递给 Exclude2 的时候。在这个阶段,TypeScript 只是处理了属性名的字符串,而不是保留了完整的属性描述符。*/typeExclude2 <T ,K extendsT > =T extendsK ? never :T ;typeMyOmit2 <T ,K extends keyofT > = {[P inExclude <keyofT ,K >]:T [P ]}
ts
//方案2的正确版本typeExclude3 <T ,K > =T extendsK ? never :T ;typeMyOmit3 <T ,K extendsT > = {[P in keyofT asExclude3 <P ,K >]:T [P ]}
ts
//方案2的正确版本typeExclude3 <T ,K > =T extendsK ? never :T ;typeMyOmit3 <T ,K extendsT > = {[P in keyofT asExclude3 <P ,K >]:T [P ]}