Type 'X' is not assignable to type 'Y' (TS2322)
Solve TypeScript TS2322 compilation error. Understand structural typing, excess property checks, optional chaining, and proper union narrowing.
Root Cause Mechanical Summary
A variable or function parameter was assigned a value whose structural type conflicts with the declared type contract. TypeScript’s static analyzer rejects the assignment to prevent runtime property access failures.
TypeScript relies on structural subtyping. If type A lacks required properties declared on type B, or property primitive types conflict (e.g. `string | null` assigned to `string`), TS2322 is emitted.
// TS2322: Type 'string | null' is not assignable to type 'string'
function sendEmail(email: string) { /* ... */ }
const userEmail: string | null = getUserEmail();
sendEmail(userEmail);// Narrow the type before calling
function sendEmail(email: string) { /* ... */ }
const userEmail: string | null = getUserEmail();
if (userEmail !== null) {
sendEmail(userEmail); // Narrowed to string safely
} else {
// Handle fallback or throw error
}Resolution Note: Use type guards (`if (val !== null)`) or nullish coalescing to satisfy non-nullable contracts.
Step-by-Step Triage Checklist
Examine the specific property identified in the compiler error diagnostic.
Check if `strictNullChecks` is enabled in `tsconfig.json`.
Use type narrowing or type assertions (`as Type`) only when runtime checks guarantee validity.
Typecheck Quality Gate in CI
Prevent recurrence by enforcing this verification check in staging or pre-commit hooks:
name: Typecheck
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: bun install
- run: bun run typecheck
DevFlow Diagnostic Workbench Tools
Frequently Asked Questions
- What is the difference between TS2322 and TS2345?
- TS2322 is emitted on variable assignment (`const a: string = 123;`), while TS2345 is emitted when passing arguments to a function call.