Skip to content

Item 61: Use Record Types to Keep Values in Sync

要点

  • Recognize the fail open versus fail closed dilemma.
  • Use ++Record++ types to keep related values and types synchronized.
  • Consider using ++Record++ types to force choices when adding new properties to an interface.
  • 认识到“失败开放”(fail open)与“失败封闭”(fail closed)之间的两难问题。
  • 使用 Record 类型来保持相关值和类型的同步。
  • 在向接口添加新属性时,可以考虑使用 Record 类型来强制做出选择。

正文

ts
interface ScatterProps {
  // The data
  xs: number[]
  ys: number[]

  // Display
  xRange: [number, number]
  yRange: [number, number]
  color: string

  // Events
  onClick?: (x: number, y: number, index: number) => void
}

💻 playground


ts
function shouldUpdate(oldProps: ScatterProps, newProps: ScatterProps) {
  for (const kStr in oldProps) {
    const k = kStr as keyof ScatterProps
    if (oldProps[k] !== newProps[k]) {
      if (k !== 'onClick') return true
    }
  }
  return false
}

💻 playground


ts
function shouldUpdate(oldProps: ScatterProps, newProps: ScatterProps) {
  return (
    oldProps.xs !== newProps.xs ||
    oldProps.ys !== newProps.ys ||
    oldProps.xRange !== newProps.xRange ||
    oldProps.yRange !== newProps.yRange ||
    oldProps.color !== newProps.color
    // (no check for onClick)
  )
}

💻 playground


ts
interface ScatterProps {
  xs: number[]
  ys: number[]
  // ...
  onClick?: (x: number, y: number, index: number) => void

  // Note: if you add a property here, update shouldUpdate!
}

💻 playground


ts
const REQUIRES_UPDATE: Record<keyof ScatterProps, boolean> = {
  xs: true,
  ys: true,
  xRange: true,
  yRange: true,
  color: true,
  onClick: false,
}

function shouldUpdate(oldProps: ScatterProps, newProps: ScatterProps) {
  for (const kStr in oldProps) {
    const k = kStr as keyof ScatterProps
    if (oldProps[k] !== newProps[k] && REQUIRES_UPDATE[k]) {
      return true
    }
  }
  return false
}

💻 playground


ts
interface ScatterProps {
  // ...
  onDoubleClick?: () => void
}

💻 playground


ts
const REQUIRES_UPDATE: Record<keyof ScatterProps, boolean> = {
  //  ~~~~~~~~~~~~~~~ Property 'onDoubleClick' is missing in type ...
  // ...
}

💻 playground


ts
const PROPS_REQUIRING_UPDATE: (keyof ScatterProps)[] = [
  'xs',
  'ys',
  // ...
]

💻 playground

Released under the MIT License.