← Debugging Guides

阅读中文版本

TypeScript — TS2322: Type is not assignable to type

Resolve TS2322 by aligning the declared and actual types, widening narrow literals or narrowing unions correctly.

beginnerdebuggingtypescript

Symptoms

  • error TS2322: Type 'string' is not assignable to type 'number'
  • The error appears after changing a function signature
  • Assigning a specific value to a union fails
  • Object literals have excess or missing properties

Possible causes

  • The value type does not match the declared variable or parameter type
  • A string literal is inferred wider than the expected union member
  • An object has properties outside the target shape or lacks required ones
  • Null or undefined is not included in the target type

Diagnosis steps

Read both types in the message

npx tsc --noEmit

Interpretation

The message names the source type and the target type. Comparing them shows whether the fix is widening, narrowing or adding a property.

Check the inferred literal type

npx tsc --noEmit --pretty

Interpretation

Literal values sometimes widen, which changes assignability. An explicit annotation or as const can fix it.

Confirm optionality of fields

grep -n "interface\|type " src/types.ts

Interpretation

A missing optional marker makes a field required, causing excess or missing property errors.

Root cause

TypeScript inferred a type for the value that is not assignable to the declared target, because of a genuine mismatch, an unexpected widening, or a shape that differs from the expected interface.

Fix

Align the value and target types by converting the value, widening or narrowing the declaration, adding missing optional markers, or making the shape match the expected type exactly.

Verify the fix

Run the type checker again and confirm the error is gone, then run tests to confirm the runtime behavior still matches.

Symptom walkthrough

The compiler reports TS2322 with the source and target types in the message. The failure can be a genuine mismatch, but it also arises from type inference: a value inferred wider than a union member, an object literal with an extra property, or a field that is required when the target marks it optional. Reading both sides of the message is usually enough to see which it is.

Fix in practice

Make the two sides agree: convert or parse the value, annotate a literal with as const or an explicit type, add optional markers to match the target, or adjust the target to include the value. Avoid casting with any, which silences the check without fixing the mismatch.

Verification

Rerun the type checker and confirm the error is gone, then run the tests to confirm runtime behavior still matches expectations. Passing types with failing behavior is not a real fix.

Diagnostic commands

Check the behavior with commands like these:

npx tsc --noEmit
npx tsc --noEmit --pretty
grep -n "interface\|type " src/types.ts