<!--
title: Explicit Null Semantics
domain: ai-agents
topic: Null Handling
language: TSX
source: aaif-goose/goose
updated: 2026-07-22
url: https://awesomereviewers.com/reviewers/goose-explicit-null-semantics/
-->

When handling optional/nullable values in TypeScript/React, make “unset/default” distinct from “legitimate empty/zero” and avoid truthiness-based guards.

Apply:
1) Use a dedicated sentinel for “never set”
- Prefer `null`/`undefined` to represent “unset”, especially when `0`, `''`, or `false` are meaningful.
2) Check explicitly for sentinel/optionals
- Prefer `value !== undefined` / `value != null` over `if (value)` when the value may be `0` or `''`.
3) Normalize before branching
- For user input, normalize (`trim`) before deciding which code path applies.
4) Validate using the intended combined condition
- Compute derived state first, then apply the combined predicate.

Example (sentinel + explicit checks):

```ts
// Sentinel models “never set” separately from a real 0.
const [navExpandedWidth, setNavExpandedWidth] = useState<number | null>(null);

useEffect(() => {
  window.electron.getSetting('navExpandedWidth').then((stored: number | null) => {
    if (stored === null) {
      // keep component default
      return;
    }

    // stored === 0 is a legitimate explicit value, not “unset”
    setNavExpandedWidth(stored);
  });
}, []);

// Explicit optional check (don’t rely on truthiness)
const initialMessage = editedMessage !== undefined
  ? { msg: editedMessage, images: [] }
  : undefined;
```

This prevents bugs where guards accidentally skip applying valid persisted values (e.g., `0`) or mis-handle empty-but-present content (e.g., `''`).
