Readonly2
介绍
实现MyReadonly2<T,K>
, 其接收两个类型参数T
和K
K
指定T
属性集合中应该设置为只读. 当K
没有提供, 应该让所有属性只读,就像通常的Readonly<T>
例如
ts
interface Todo {title: stringdescription: stringcompleted: boolean}const todo: MyReadonly2<Todo, 'title' | 'description'> = {title: "Hey",description: "foobar",completed: false,}todo.title = "Hello" // Error: cannot reassign a readonly propertytodo.description = "barFoo" // Error: cannot reassign a readonly propertytodo.completed = true // OK
View on GitHubts
interface Todo {title: stringdescription: stringcompleted: boolean}const todo: MyReadonly2<Todo, 'title' | 'description'> = {title: "Hey",description: "foobar",completed: false,}todo.title = "Hello" // Error: cannot reassign a readonly propertytodo.description = "barFoo" // Error: cannot reassign a readonly propertytodo.completed = true // OK
start point
ts
/* _____________ Your Code Here _____________ */typeMyReadonly2 <T ,K > = any/* _____________ Test Cases _____________ */typecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Alike <MyReadonly2 <Todo1 , 'title' | 'description'>,Expected >>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Alike <MyReadonly2 <Todo2 , 'title' | 'description'>,Expected >>,]interfaceTodo1 {title : stringdescription ?: stringcompleted : boolean}interfaceTodo2 {readonlytitle : stringdescription ?: stringcompleted : boolean}interfaceExpected {readonlytitle : stringreadonlydescription ?: stringcompleted : boolean}
take the challengets
/* _____________ Your Code Here _____________ */typeMyReadonly2 <T ,K > = any/* _____________ Test Cases _____________ */typecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Alike <MyReadonly2 <Todo1 , 'title' | 'description'>,Expected >>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Alike <MyReadonly2 <Todo2 , 'title' | 'description'>,Expected >>,]interfaceTodo1 {title : stringdescription ?: stringcompleted : boolean}interfaceTodo2 {readonlytitle : stringdescription ?: stringcompleted : boolean}interfaceExpected {readonlytitle : stringreadonlydescription ?: stringcompleted : boolean}
my solutions
Spoiler warning // Click to reveal answer
ts
//方案1typeMyReadonly2 <T ,K extends keyofT = keyofT > = {readonly [P in keyofT asP extendsK ?P : never]:T [P ]} & {[P in keyofT asP extendsK ? never :P ]:T [P ]}
ts
//方案1typeMyReadonly2 <T ,K extends keyofT = keyofT > = {readonly [P in keyofT asP extendsK ?P : never]:T [P ]} & {[P in keyofT asP extendsK ? never :P ]:T [P ]}
ts
//方案2 方案1的变种typePick2 <T ,K extends keyofT > = {readonly [P in keyofT asP extendsK ?P : never]:T [P ]}typeOmit2 <T ,K extends keyofT > = {[P in keyofT asP extendsK ? never :P ]:T [P ]}typeMyReadonly2 <T ,K extends keyofT = keyofT > =Pick2 <T ,K > &Omit2 <T ,K >
ts
//方案2 方案1的变种typePick2 <T ,K extends keyofT > = {readonly [P in keyofT asP extendsK ?P : never]:T [P ]}typeOmit2 <T ,K extends keyofT > = {[P in keyofT asP extendsK ? never :P ]:T [P ]}typeMyReadonly2 <T ,K extends keyofT = keyofT > =Pick2 <T ,K > &Omit2 <T ,K >
ts
//方案3 most populartypeMyReadonly2 <T ,K extends keyofT = keyofT > =Omit <T ,K > &Readonly <Pick <T ,K >>
ts
//方案3 most populartypeMyReadonly2 <T ,K extends keyofT = keyofT > =Omit <T ,K > &Readonly <Pick <T ,K >>