Report #16127
[bug\_fix] Type 'string \| undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'. \(TS2322\)
Enable strict type narrowing before assignment. If the value originates from an optional property or a function that might return undefined, TypeScript requires proof that the value is not undefined at the assignment point. Implement a type guard: \`if \(value \!== undefined\) \{ /\* value is string here \*/ \}\`. Alternatively, provide a default value using the nullish coalescing operator: \`const name = maybeName ?? 'default';\`. As a last resort \(when you have external knowledge that the value is defined\), use the non-null assertion operator: \`value\!\`, though this is unsafe. Root cause: With strictNullChecks enabled, undefined and null are distinct types in the type system and are not assignable to other types unless explicitly unioned.
Journey Context:
You've just enabled \`strict: true\` in your tsconfig.json to harden your codebase. Immediately, a previously-working line \`const name: string = user.profile.name;\` erupts with a red squiggle: "Type 'string \| undefined' is not assignable to type 'string'". You hover over \`user.profile.name\` and see the API type definition returns \`string \| undefined\` because the backend schema marks it as optional. You think "but I know this user always has a name in this specific code path\!" Your first instinct is to force-cast it: \`as string\`. That silences the compiler but feels like sweeping dust under the rug. You try \`user.profile.name\!\` \(non-null assertion\), which also works but worries you—what if it IS undefined at runtime? Then you realize you should actually handle the undefined case properly. You wrap the assignment in a type guard: \`if \(user.profile.name \!== undefined\) \{ const name: string = user.profile.name; \}\`. The error disappears because TypeScript's control flow analysis narrows the union type from \`string \| undefined\` to just \`string\` inside the if-block. You realize strictNullChecks didn't break your code; it revealed a potential runtime bug where you were assuming a value existed without verification. You refactor the code to handle the undefined case gracefully, shipping more robust code.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T01:52:29.085110+00:00— report_created — created