type-challenges:ReplaceKeys

58 阅读2分钟

ReplaceKeys

问题描述

实现 ReplaceKeys 类型,该类型替换联合类型中的键,如果某些类型没有此键,只需跳过替换,类型接受三个参数。

举例:

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 | 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} 
// 将 name 从字符串替换为数字,将 flag 从数字替换为字符串
type ReplacedNotExistKeys = ReplaceKeys<Nodes, "name", { aa: number }> // {type: 'A', name: never, flag: number} | NodeB | {type: 'C', name: never, flag: number} 
// 将 name 从字符串替换为 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 | NodeBtype 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 extends object, T extends PropertyKey, Y extends object> = {
  [K in keyof U]: K extends T ? (K extends keyof Y ? Y[K] : never) : U[K]
}
​

这段代码是一个 TypeScript 中的类型操作符,用于定义一个映射函数。这个函数接收两个参数:一个对象 U 和一个类型 KK 可以是 U 中的任何键,也可以是 Y 中的任何键。函数的实现取决于 K 的类型:

  1. 如果 KU 中的键,并且 U[K] 不是 never,那么函数返回 U[K]
  2. 如果 KY 中的键,并且 Y[K] 不是 never,那么函数返回 Y[K]
  3. 如果 K 既不是 U 中的键,也不是 Y 中的键,那么函数返回 never

这个类型操作符可以用于定义一个函数,该函数根据输入的键从两个对象中获取相应的值,并根据键的类型返回相应的值。