Skip to content
webtype.orgwebtype.orgtsconfig

    ↑↓ move · ⏎ open · esc close

    tsconfig

    useUnknownInCatchVariables

    What was thrown is not an Error

    JavaScript can throw anything — a string, undefined, a number — so a caught value is `unknown` rather than `any`.

    Since
    TypeScript 4.4
    strict
    In strict
    In your tsconfig
    "useUnknownInCatchVariables": true
    Compiled with
    "strict": true

    The same snippet both times. Only the option changed.

    With it off

    "useUnknownInCatchVariables": false
    export function run() {
      try {
        throw new Error('boom')
      } catch (error) {
        return error.message
      }
    }

    Compiles clean

    With it on

    "useUnknownInCatchVariables": true
    export function run() {
      try {
        throw new Error('boom')
      } catch (error) {
        return error.message
      }
    }

    Emits TS18046

    Why the compiler bothers

    `error.message` on a caught value is the single most common unchecked assumption in a typed codebase, and it is wrong far more often than it looks: a rejected promise carrying a string, a library throwing a plain object, a `null` from code that predates all of this. `unknown` forces the narrowing that was always required — `error instanceof Error` — and the cost is one line at each catch, once.

    Takeaway

    Narrow it once at the boundary, not at every use inside the block.

    Where to go next

    22 options