ReplaceKeys
介绍
实现一个ReplaceKeys类型, 代替联合类型中的keys, 如果类型中没有这个key, 跳过替换. 类型会接收3个参数
例如:
ts
type NodeA = {type: "A"name: stringflag: number}type NodeB = {type: "B"id: numberflag: number}type NodeC = {type: "C"name: stringflag: number}type Nodes = NodeA | NodeB | NodeCtype ReplacedNodes = ReplaceKeys<Nodes,"name" | "flag",{ name: number; flag: string }> // {type: 'A', name: number, flag: string} | {type: 'B', id: number, flag: string} | {type: 'C', name: number, flag: string} // would replace name from string to number, replace flag from number to string.type ReplacedNotExistKeys = ReplaceKeys<Nodes, "name", { aa: number }> // {type: 'A', name: never, flag: number} | NodeB | {type: 'C', name: never, flag: number} // would replace name to never
View on GitHubts
type NodeA = {type: "A"name: stringflag: number}type NodeB = {type: "B"id: numberflag: number}type NodeC = {type: "C"name: stringflag: number}type Nodes = NodeA | NodeB | NodeCtype ReplacedNodes = ReplaceKeys<Nodes,"name" | "flag",{ name: number; flag: string }> // {type: 'A', name: number, flag: string} | {type: 'B', id: number, flag: string} | {type: 'C', name: number, flag: string} // would replace name from string to number, replace flag from number to string.type ReplacedNotExistKeys = ReplaceKeys<Nodes, "name", { aa: number }> // {type: 'A', name: never, flag: number} | NodeB | {type: 'C', name: never, flag: number} // would replace name to never
起点
ts
/* _____________ Your Code Here _____________ */typeReplaceKeys <U ,T ,Y > = any/* _____________ Test Cases _____________ */typeNodeA = {type : 'A'name : stringflag : number}typeNodeB = {type : 'B'id : numberflag : number}typeNodeC = {type : 'C'name : stringflag : number}typeReplacedNodeA = {type : 'A'name : numberflag : string}typeReplacedNodeB = {type : 'B'id : numberflag : string}typeReplacedNodeC = {type : 'C'name : numberflag : string}typeNoNameNodeA = {type : 'A'flag : numbername : never}typeNoNameNodeC = {type : 'C'flag : numbername : never}typeNodes =NodeA |NodeB |NodeC typeReplacedNodes =ReplacedNodeA |ReplacedNodeB |ReplacedNodeC typeNodesNoName =NoNameNodeA |NoNameNodeC |NodeB typecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <ReplaceKeys <Nodes , 'name' | 'flag', {name : number,flag : string }>,ReplacedNodes >>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <ReplaceKeys <Nodes , 'name', {aa : number }>,NodesNoName >>,]
take the challengets
/* _____________ Your Code Here _____________ */typeReplaceKeys <U ,T ,Y > = any/* _____________ Test Cases _____________ */typeNodeA = {type : 'A'name : stringflag : number}typeNodeB = {type : 'B'id : numberflag : number}typeNodeC = {type : 'C'name : stringflag : number}typeReplacedNodeA = {type : 'A'name : numberflag : string}typeReplacedNodeB = {type : 'B'id : numberflag : string}typeReplacedNodeC = {type : 'C'name : numberflag : string}typeNoNameNodeA = {type : 'A'flag : numbername : never}typeNoNameNodeC = {type : 'C'flag : numbername : never}typeNodes =NodeA |NodeB |NodeC typeReplacedNodes =ReplacedNodeA |ReplacedNodeB |ReplacedNodeC typeNodesNoName =NoNameNodeA |NoNameNodeC |NodeB typecases = [Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <ReplaceKeys <Nodes , 'name' | 'flag', {name : number,flag : string }>,ReplacedNodes >>,Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.Expect <Equal <ReplaceKeys <Nodes , 'name', {aa : number }>,NodesNoName >>,]
解决方案
Spoiler warning // Click to reveal answer
ts
// most populartypeReplaceKeys <U ,T ,Y > = { [K in keyofU ]:K extendsT ?K extends keyofY ?Y [K ] : never :U [K ] }
ts
// most populartypeReplaceKeys <U ,T ,Y > = { [K in keyofU ]:K extendsT ?K extends keyofY ?Y [K ] : never :U [K ] }