题目描述
Implement a type ReplaceKeys, that replace keys in union types, if some type has not this key, just skip replacing, A type takes three arguments.
For example:
type NodeA = {
type: "A"
name: string
flag: number
}
type NodeB = {
type: "B"
id: number
flag: number
}
type NodeC = {
type: "C"
name: string
flag: number
}
type Nodes = NodeA | NodeB | NodeC
type 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
题解
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type NodeA = {
type: 'A'
name: string
flag: number
}
type NodeB = {
type: 'B'
id: number
flag: number
}
type NodeC = {
type: 'C'
name: string
flag: number
}
type ReplacedNodeA = {
type: 'A'
name: number
flag: string
}
type ReplacedNodeB = {
type: 'B'
id: number
flag: string
}
type ReplacedNodeC = {
type: 'C'
name: number
flag: string
}
type NoNameNodeA = {
type: 'A'
flag: number
name: never
}
type NoNameNodeC = {
type: 'C'
flag: number
name: never
}
type Nodes = NodeA | NodeB | NodeC
type ReplacedNodes = ReplacedNodeA | ReplacedNodeB | ReplacedNodeC
type NodesNoName = NoNameNodeA | NoNameNodeC | NodeB
type cases = [
Expect<Equal<ReplaceKeys<Nodes, 'name' | 'flag', { name: number; flag: string }>, ReplacedNodes>>,
Expect<Equal<ReplaceKeys<Nodes, 'name', { aa: number }>, NodesNoName>>,
]
// ============= Your Code Here =============
type ReplaceKeys<U, T, V> = {
[P in keyof U]: P extends T
? P extends keyof V
? V[P]
: never
: U[P]
}
条件类型
type ReplaceKeys<U, T, V> = {
[P in keyof U]: P extends T
? P extends keyof V
? V[P]
: never
: U[P]
}
-
遍历
U的每个键P:[P in keyof U]:遍历U的所有键
-
条件判断:
-
如果
P是T中的键:-
如果
P是V中的键,使用V[P]替换U[P] -
如果
P不是V中的键,使用never
-
-
如果
P不是T中的键,保留U[P]
-