TS2322Semantic Error
Since TS 1.0Updated in TS 4.0Updated in TS 4.9

Fix TS2322: Type Not Assignable

Learn why TypeScript throws TS2322 when a value doesn't match the expected type, and how to fix type assignability errors with practical examples.

error TS2322: Type 'X' is not assignable to type 'Y'

What This Error Means

TS2322 is the most common TypeScript error you will encounter. It fires whenever you try to put a value into a slot that expects a different type. Think of it as TypeScript telling you: "You promised this would be an X, but you're giving me a Y."

This is the backbone of TypeScript's type system. Every time you assign a value to a variable, pass a prop to a React component, or return a value from a function, TypeScript checks that the types line up. When they don't, you get TS2322.

// The general shape of the error:
// Type 'string' is not assignable to type 'number'.
//       ~~~~~~                             ~~~~~~
//       what you gave                      what was expected

Common Causes

1. Assigning the Wrong Primitive Type

This is the simplest case. You declared a variable with one type but tried to assign a value of another.

// ❌ Broken
let userAge: number = "twenty-five"
//  ~~~~~~~ Error: Type 'string' is not assignable to type 'number'.
// ✅ Fixed — use the correct type
let userAge: number = 25

2. Object Literal Missing or Extra Properties

When you assign an object literal directly, TypeScript performs excess property checking. Any property not defined in the target type triggers TS2322.

// ❌ Broken
interface UserProfile {
  name: string
  email: string
}
 
const profile: UserProfile = {
  name: "Ada Lovelace",
  email: "ada@example.com",
  role: "admin", // Error: Object literal may only specify known properties.
}
// ✅ Fixed — remove the extra property or extend the interface
interface UserProfile {
  name: string
  email: string
  role?: string // add it as optional if needed
}
 
const profile: UserProfile = {
  name: "Ada Lovelace",
  email: "ada@example.com",
  role: "admin",
}

3. Incorrect Return Type in a Function

If your function's return type annotation doesn't match what you actually return, TypeScript catches it.

// ❌ Broken
function getDiscountPercentage(tier: string): number {
  if (tier === "premium") return 20
  return "none"
  //     ~~~~~~ Error: Type 'string' is not assignable to type 'number'.
}
// ✅ Fixed — return a number for all paths
function getDiscountPercentage(tier: string): number {
  if (tier === "premium") return 20
  return 0
}

4. Passing Wrong Props to a React Component

In React projects, TS2322 often appears when a component receives props that don't match its type definition.

// ❌ Broken
interface ButtonProps {
  variant: "primary" | "secondary"
  disabled: boolean
}
 
function AppButton(props: ButtonProps) { /* ... */ }
 
// In another component:
<AppButton variant="danger" disabled={false} />
//         ~~~~~~~ Error: Type '"danger"' is not assignable to type '"primary" | "secondary"'.
// ✅ Fixed — use a valid variant
<AppButton variant="primary" disabled={false} />

How to Fix It

Follow these steps when you see TS2322:

  1. Read the full error message. TypeScript tells you the source type (what you provided) and the target type (what was expected). Start there.

  2. Check the variable or parameter declaration. Go to where the type is defined. Is the annotation correct, or does it need to be widened?

  3. Check the value you're assigning. Is it coming from an API response, user input, or another function? The value itself might be wrong.

  4. Decide which side to fix:

    • If the type annotation is too narrow, widen it (e.g., add a union member).
    • If the value is wrong, fix the source so it produces the correct type.
    • If you need a type conversion, use explicit conversion functions like Number(), String(), or Boolean() rather than type assertions.
  5. Avoid as casts as a first resort. Type assertions silence the error but don't fix the underlying problem. They can hide real bugs that surface at runtime.

// Prefer explicit conversion over assertion
const inputValue = document.getElementById("age") as HTMLInputElement
const userAge: number = Number(inputValue.value) // safe conversion
 
// Avoid this pattern
const userAge: number = inputValue.value as unknown as number // unsafe!

FAQ

What causes TypeScript error TS2322?

TS2322 occurs when you try to assign a value to a variable, parameter, or property whose type doesn't accept that value. This is TypeScript's core type safety check preventing type mismatches.

For example, if you declare let count: number and then write count = "five", TypeScript raises TS2322 because string is not assignable to number. The same logic applies to function return types, object properties, and React component props.

How do I fix TS2322: Type 'string' is not assignable to type 'number'?

You have three options depending on what's correct for your situation:

// Option 1: Change the annotation to accept strings
let quantity: string | number = "ten"
 
// Option 2: Convert the value to the expected type
let quantity: number = Number("10")
 
// Option 3: Fix the source of the value
let quantity: number = getQuantityFromCart() // ensure this returns number

The right choice depends on your domain logic. If the value genuinely should be a number, convert it or fix the source. If both types are valid, widen the annotation with a union type.

Can I suppress TS2322 without fixing it?

Technically yes, but it is almost always a bad idea:

// @ts-ignore — suppresses the error on the next line
// @ts-expect-error — same, but errors if there's nothing to suppress (safer)
const userId: number = "abc" as any

Both @ts-ignore and type assertions (as) bypass the type system entirely. This means TypeScript can no longer protect you from runtime type errors on that line. Reserve these escape hatches for genuinely exceptional cases like working around third-party library type bugs, and always leave a comment explaining why.

Related Errors

Practice This

Put your understanding to the test with these related challenges.

Related Concepts

Share this reference

Stay Updated

Get the latest TypeScript tips, tutorials, and course updates delivered straight to your inbox.

No spam, unsubscribe at any time.