TypeScript’s type checker is throwing a fit because it can’t reconcile two distinct types, meaning a value you’re trying to use isn’t shaped in a way that matches what the code expects.

This usually happens when you’re assigning a value from one variable or expression to another, and the compiler can’t guarantee that the source type is compatible with the target type. It’s a safety mechanism to prevent runtime errors by catching potential mismatches at compile time.

Here are the most common reasons you’re seeing TS2322:

  1. Incorrectly typed function arguments or return values: You’re passing an argument to a function that doesn’t match the parameter’s type, or a function is returning a value that doesn’t match its declared return type.

    • Diagnosis: Hover over the function call or the function definition in your IDE. TypeScript will highlight the mismatch.
    • Fix: Ensure the type of the argument passed to the function precisely matches the type of the parameter. If it’s a return type issue, adjust the function’s implementation to return a value of the declared type, or update the function’s return type annotation to accurately reflect what it returns.
    • Why it works: TypeScript enforces strict type compatibility. If function foo(bar: string) is called with foo(123), the compiler sees number (123) is not assignable to string (bar).
  2. Assigning a more general type to a more specific type: You’re trying to assign a value that could be null or undefined to a variable that is explicitly typed not to be.

    • Diagnosis: Check the type annotation of the variable you’re assigning to. Look for strict null checks enabled in your tsconfig.json ( "strictNullChecks": true is the default in newer projects).
    • Fix: Either adjust the target variable’s type to allow null or undefined (e.g., let myVar: string | null;), or ensure the value being assigned is guaranteed not to be null/undefined. A common pattern is using a non-null assertion operator (!) if you’re absolutely certain, though this bypasses type safety: myVar = potentiallyNullValue!;.
    • Why it works: If strictNullChecks is on, string is not assignable to string | null | undefined. You must explicitly allow null or undefined in the target type.
  3. Mismatched object property types: You’re assigning an object to a variable or passing it to a function, and one or more of its properties have types that don’t match the expected interface or type definition.

    • Diagnosis: Compare the structure and types of the object you’re creating/using against the interface or type definition it’s supposed to conform to.
    • Fix: Ensure every property on the source object has a type that is assignable to the corresponding property type in the target interface/type. If the source object is missing a required property, add it. If a property’s type is too narrow, widen it.
    • Why it works: If interface User { id: number; name: string; } and you have const user = { id: 1, name: 'Alice', age: 30 };, TypeScript will flag age because the User interface doesn’t have an age property. If you try to assign { id: '123' } to a variable typed as User, it will fail because string ('123') is not assignable to number (id).
  4. Using generic types incorrectly: When working with generic functions or classes, the type arguments you provide might not be compatible with the constraints defined on the generic type parameters.

    • Diagnosis: Examine the generic type definition and the type arguments you’re supplying. Look for specific constraints (e.g., T extends { length: number }).
    • Fix: Ensure the types you’re using as type arguments satisfy all constraints. For example, if a generic function expects T extends string, you cannot pass number as T.
    • Why it works: Generics have rules. If function processArray<T extends { id: number }>(items: T[]) is called with [{ name: 'a' }], the compiler sees that { name: 'a' } does not have an id property of type number, violating the constraint.
  5. Assigning an array of a specific type to an array of a more general type (or vice-versa unexpectedly): TypeScript’s array covariance/contravariance rules can be tricky. You can’t always assign Derived[] to Base[] directly if Derived is a subtype of Base when you expect it to work.

    • Diagnosis: Check the types of the arrays involved. For example, string[] vs. any[] or string[] vs. (string | number)[].
    • Fix: Use as or type assertions if you’re certain, but preferably, adjust the types to be compatible. Often, creating a new array or using Array.prototype.map to transform elements can resolve this. For example, const strings: string[] = ['a', 'b']; const general: (string | number)[] = [...strings]; would work.
    • Why it works: string[] is not assignable to number[] because you can’t safely treat a string as a number. Conversely, while number[] can be assigned to (string | number)[], the other way around isn’t safe if the target array might contain numbers. The compiler will often warn if you try to assign (string | number)[] to string[].
  6. Third-party library types not matching your usage: If you’re using a library, its declared types might not align with how you’re trying to use its components, especially with older or poorly typed libraries.

    • Diagnosis: Look at the type definitions (.d.ts files) for the library or hover over the library’s imported types in your code. Compare them to how you are instantiating or calling them.
    • Fix: Update the library to the latest version if possible. If the issue persists, you might need to use type assertions (as any) as a last resort, or, more ideally, create a declaration file (.d.ts) to augment or override the library’s types to match your specific usage.
    • Why it works: The compiler relies on the provided type definitions. If those definitions are inaccurate for your use case, mismatches occur.

The next error you’ll likely encounter is a runtime TypeError if you manage to bypass TypeScript’s checks, or another type mismatch error as you continue to fix the current one.

Want structured learning?

Take the full Typescript course →