Skip to content
webtype.orgwebtype.orgtsconfig

    ↑↓ move · ⏎ open · esc close

    tsconfig

    exactOptionalPropertyTypes

    Missing is not the same as undefined

    `{ retries?: number }` normally also permits `{ retries: undefined }`. This flag makes the question mark mean only "may be absent".

    Since
    TypeScript 4.4
    strict
    Not in strict
    In your tsconfig
    "exactOptionalPropertyTypes": true
    Compiled with
    "strict": true

    The same snippet both times. Only the option changed.

    With it off

    "exactOptionalPropertyTypes": false
    type Options = { retries?: number }
    
    export const options: Options = { retries: undefined }

    Compiles clean

    With it on

    "exactOptionalPropertyTypes": true
    type Options = { retries?: number }
    
    export const options: Options = { retries: undefined }

    Emits TS2375

    Why the compiler bothers

    The two are different at runtime and the difference is load-bearing: `"retries" in options` is false for one and true for the other, `Object.keys` lists one and not the other, and a merge that spreads defaults will have the explicit `undefined` overwrite the default while the absent key does not. Without this flag the type system cannot tell them apart, so the one API shape where it matters most — an options object with defaults — is exactly the one it cannot describe.

    Takeaway

    Write `retries?: number | undefined` when you really do accept both.

    Where to go next

    22 options