Skip to content

Item 36: Use a Distinct Type for Special Values

要点

  • Avoid special values that are assignable to regular values in a type. They will reduce TypeScript's ability to find bugs in your code.
  • Prefer null or undefined as a special value instead of 0, -1, or "".
  • Consider using a tagged union rather than null or undefined if the meaning of those values isn't clear.
  • 避免将特殊值赋给常规类型的值,这会降低 TypeScript 发现代码中 bug 的能力。
  • 优先使用 nullundefined 作为特殊值,而不是 0-1""
  • 如果特殊值的意义不明确,考虑使用标签联合类型(tagged union)代替 nullundefined

正文

ts
function splitAround<T>(vals: readonly T[], val: T): [T[], T[]] {
  const index = vals.indexOf(val)
  return [vals.slice(0, index), vals.slice(index + 1)]
}

💻 playground


ts
function safeIndexOf<T>(vals: readonly T[], val: T): number | null {
  const index = vals.indexOf(val)
  return index === -1 ? null : index
}

💻 playground


ts
function splitAround<T>(vals: readonly T[], val: T): [T[], T[]] {
  const index = safeIndexOf(vals, val)
  return [vals.slice(0, index), vals.slice(index + 1)]
  //                    ~~~~~              ~~~~~ 'index' is possibly 'null'
}

💻 playground


ts
function splitAround<T>(vals: readonly T[], val: T): [T[], T[]] {
  const index = safeIndexOf(vals, val)
  if (index === null) {
    return [[...vals], []]
  }
  return [vals.slice(0, index), vals.slice(index + 1)] // ok
}

💻 playground


ts
interface Product {
  title: string
  priceDollars: number
}

💻 playground


ts
interface Product {
  title: string
  /** Price of the product in dollars, or -1 if price is unknown */
  priceDollars: number
}

💻 playground


ts
// @strictNullChecks: false
const truck: Product = {
  title: 'Tesla Cybertruck',
  priceDollars: null, // ok
}

💻 playground

Released under the MIT License.