How to fix Type is not assignable to itself in TypeScript
This error occurs when TypeScript detects that two seemingly identical types are actually incompatible, often due to duplicate package versions, circular type references, or complex conditional type inference issues.
Quick fix
Fixes Type is not assignable to itself
npm ls <package-name>
# Example: npm ls @babel/types- Check for duplicate package versions
- Use selective version resolution (Yarn)
- Use overrides (npm 8.3+)
- Clear package manager cache
npm ls <package-name># Example: npm ls @babel/typesType is not assignable to itself
What this error means
The "Type is not assignable to itself" error is one of TypeScript's most confusing messages because it appears to violate basic logic - how can a type not be compatible with itself? This error occurs when TypeScript's type system determines that what appears to be the same type is actually represented by two different, incompatible type instances. The most common cause is duplicate package installations where different versions of the same package create separate type definitions. For example, if you have two versions of @babel/types installed, TypeScript treats TSTypeAliasDeclaration from version 7.4.0 as incompatible with TSTypeAliasDeclaration from version 7.5.0, even though they have the same name. The error can also occur with complex type scenarios involving circular references, conditional types with infer, or branded/template literal types where TypeScript's type inference creates multiple representations of what should be the same type.
Typical symptoms
- Error message states "Type 'X' is not assignable to type 'X'" with identical type names
- Error appears in code that should work logically, with no apparent type mismatch
- Error message includes "two different types with this name exist, but they are unrelated"
- Error occurs after updating dependencies or adding new packages
- Compilation fails despite types appearing identical in the code
- Error appears when using complex conditional types or infer keyword
Common causes
- Multiple versions of the same package installed (most common with @babel/types, @types/node, etc.)
- Yarn or npm cache contains outdated package versions that conflict with dependency ranges
- Circular type references where a type extends or references itself directly or indirectly
- Complex conditional types with infer that TypeScript evaluates differently in different contexts
- Branded types or template literal types creating multiple incompatible representations
- Type aliases with circular dependencies in Record or mapped types
- Monorepo workspace with multiple versions of the same dependency
How to fix "Type is not assignable to itself"
First, identify if you have duplicate versions of packages installed. This is the most common cause.
For npm:
npm ls <package-name>
# Example: npm ls @babel/typesFor yarn:
yarn why <package-name>
# Example: yarn why @babel/typesFor pnpm:
pnpm why <package-name>Look for multiple version numbers in the output. If you see different versions, proceed to the next steps.
If you're using Yarn, force all packages to use the same version by adding a resolutions field to your package.json:
{
"resolutions": {
"@babel/types": "^7.23.0",
"@types/node": "^20.0.0"
}
}Then reinstall dependencies:
rm -rf node_modules yarn.lock
yarn installReplace the version numbers with the latest compatible version for your project.
For npm version 8.3 or later, use the overrides field in package.json:
{
"overrides": {
"@babel/types": "^7.23.0",
"@types/node": "^20.0.0"
}
}Then clean install:
rm -rf node_modules package-lock.json
npm installCached packages can cause version conflicts. Clear your package manager's cache:
For npm:
npm cache clean --forceFor yarn:
yarn cache cleanFor pnpm:
pnpm store pruneAfter clearing the cache, reinstall all dependencies:
rm -rf node_modules
npm install # or yarn install / pnpm installIf the error involves circular type references, restructure your types to avoid self-referential inheritance:
Problematic:
// Don't do this - circular inheritance
interface A extends B {}
interface B extends A {}
// Or this - type alias referencing itself
type Tree = {
value: string;
children: Tree[]; // This can work as a property
}
type BadTree = Tree | BadTree[]; // But not in a unionFixed:
// Use properties instead of inheritance
interface Node {
next?: Node; // Property reference is OK
value: string;
}
// Or use an interface for recursive structures
interface TreeNode {
value: string;
children: TreeNode[]; // Interfaces handle recursion better
}If the error occurs with conditional types using infer, try simplifying the type logic:
Problematic:
type Extract<T> = T extends Foo<infer U> ? U : T;
function process<T>(value: T): Extract<T> {
// Type is not assignable to itself
return value;
}Fixed:
// Add explicit type annotations
function process<T>(value: T): Extract<T> {
return value as Extract<T>;
}
// Or restructure to avoid conditional in return type
function process<T extends Foo<any>>(value: T): T extends Foo<infer U> ? U : never {
// ...
}Alternatively, use a helper type with fewer constraints:
type Unwrap<T> = T extends Foo<infer U> ? U : never;
function process<T extends Foo<any>>(value: T): Unwrap<T> {
return value.inner;
}Advanced notes
Monorepo Considerations: In monorepos using workspaces, this error often occurs when different packages depend on different versions of shared types. Use a root-level package.json with resolutions/overrides to enforce consistent versions across all workspace packages.
TypeScript Version Sensitivity: Some complex type scenarios that trigger this error in older TypeScript versions may be resolved in newer versions. If you're using branded types or template literal types, consider upgrading to TypeScript 5.0+ which has improved type inference.
Branded Types: When using branded types (nominal typing), ensure you're creating new branded values correctly. Mixing branded and unbranded values can trigger this error:
type UserId = string & { __brand: 'UserId' };
// Wrong - unbrandеd string
const id1: UserId = '123'; // Error
// Correct - properly branded
const id2 = '123' as UserId;Performance Impact: Deeply nested or highly complex conditional types can cause TypeScript to create multiple type representations during type checking, leading to this error. Simplifying your type definitions can improve both compilation performance and reliability.
pnpm Strict Mode: pnpm's strict dependency resolution can prevent many duplicate version issues that cause this error, but may require explicit configuration of peer dependencies in package.json.
Frequently asked questions
- What does "Type is not assignable to itself" mean?
- The "Type is not assignable to itself" error is one of TypeScript's most confusing messages because it appears to violate basic logic - how can a type not be compatible with itself? This error occurs when TypeScript's type system determines that what appears to be the same type is actually represented by two different, incompatible type instances. The most common cause is duplicate package installations where different versions of the same package create separate type definitions.
- How do I fix "Type is not assignable to itself"?
- This error occurs when TypeScript detects that two seemingly identical types are actually incompatible, often due to duplicate package versions, circular type references, or complex conditional type inference issues.
- What causes "Type is not assignable to itself"?
- Multiple versions of the same package installed (most common with @babel/types, @types/node, etc.) Yarn or npm cache contains outdated package versions that conflict with dependency ranges Circular type references where a type extends or references itself directly or indirectly
- Is the "Type is not assignable to itself" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚TypeScript Official Documentation
- 📖Typescriptlang.org - type-compatibility.html(Official Docs)
- 🔗
- 🐙Github.com - 61098(GitHub)
- 🐙Github.com - 34856(GitHub)
- 🐙Github.com - 47901(GitHub)
- 🐙Github.com - 14174(GitHub)