TypeScript "Type X Is Not Assignable to Type Y": How to Read and Fix It
TypeScript's most common error means a value doesn't match the type expected where you put it. How to read the message (including long nested ones), the common cases — string vs number, null and undefined, string literals, missing object properties, array types — and fixes that don't just hide the bug.
Type 'string' is not assignable to type 'number'.
This is TypeScript's most common error. It means: you put a value somewhere that expects a different type. The first type is what you gave; the second is what was expected. (What is TypeScript?)
Reading the message
Read it as: "[what you have] is not assignable to [what's required]".
Long errors are nested — each indented line explains why the line above failed. The last line is usually the real problem:
Type '{ name: string; age: string; }' is not assignable to type 'User'.
Types of property 'age' are incompatible.
Type 'string' is not assignable to type 'number'.
Translation: the object's age is a string, but User.age must be a number.
Common case 1: string vs number
Values from forms, URLs and localStorage are always strings:
const age: number = event.target.value // ❌ string
const age: number = Number(event.target.value) // ✅
Same for query parameters and environment variables. Convert — and validate — at the boundary. (Query parameters explained, Validating input with Zod)
Common case 2: undefined or null
Type 'string | undefined' is not assignable to type 'string'.
The value might be missing. TypeScript wants you to handle that case:
const name: string = user.nickname ?? 'Anonymous' // fallback
if (!user.nickname) return // early exit
useName(user.nickname) // now it's string
(Object is possibly undefined)
Environment variables are typed string | undefined because they might not be set:
const key = process.env.API_KEY
if (!key) throw new Error('API_KEY is not set')
Common case 3: string literal types
Type 'string' is not assignable to type '"small" | "medium" | "large"'.
The target only accepts specific strings, but TypeScript sees your value as any string:
let size = 'small' // inferred as string
<Button size={size} /> // ❌
const size = 'small' // inferred as "small" ✅
let size: 'small' | 'large' = 'small' // ✅
For objects, as const keeps literal types:
const config = { size: 'small' } as const
Common case 4: object shapes
Property 'email' is missing in type '{ name: string; }' but required in type 'User'.
You're creating or passing an object without a required field. Add it, or make the field optional in the type (email?: string) if it's genuinely optional.
And the reverse — "Object literal may only specify known properties" — means you added a property the type doesn't have, often a typo.
Common case 5: arrays
Type 'never[]' is not assignable to type 'User[]'.
An empty array with no type is inferred as never[] in some situations. Give it a type:
const [users, setUsers] = useState<User[]>([])
Common case 6: function types
Passing a function whose parameters don't match what's expected — e.g. an onChange handler typed for the wrong event:
const handle = (e: React.ChangeEvent<HTMLInputElement>) => setValue(e.target.value)
Hover over the prop in your editor to see the expected type.
Fixes to avoid
as any— switches checking off. The bug is still there; you just won't hear about it.as Useron data you haven't checked — tells TypeScript "trust me" about data that may not match. Validate API responses instead.// @ts-ignore— same problem.!(non-null assertion) — fine when you truly know, but it crashes at runtime when you're wrong.
These are especially tempting for AI tools trying to make errors disappear. If an AI fix adds as any, ask it to fix the actual type instead. (Why TypeScript makes AI-generated code safer)
Tips
- Hover over variables in VS Code to see their inferred types.
- Read from the bottom of nested errors.
- Fix types where data enters your app, and the rest of the code becomes easier.
EasySpawn runs your TypeScript project on a server with Claude Code built in — it can run tsc, read these errors and fix the types properly rather than casting them away. See how it works or join the waitlist.
Related: JavaScript vs TypeScript · Property Does Not Exist on Type · Object Is Possibly Undefined · Why TypeScript Makes AI-Generated Code Safer
Keep reading
"ReferenceError: window is not defined" in Next.js: How to Fix It
window, document and localStorage only exist in the browser. Next.js renders components on the server first, where they don't exist. Why it happens, and the fixes: useEffect, 'use client', typeof checks, dynamic imports with ssr: false, and libraries that touch window on import.
"Unexpected Token < in JSON at Position 0": What It Means and How to Fix It
Your code expected JSON and got HTML — almost always an error page or your app's index.html. Why it happens (wrong URL, 404, server error, SPA fallback, login redirect), how to see what the server actually sent, and how to parse responses safely.