Blog
3 min read

TypeScript "Property Does Not Exist on Type": Causes and Fixes

TypeScript says the property you're reading isn't part of the type. The common causes — a typo or hallucinated field, a missing field in your type, union types that need narrowing, unknown/{} types, window and process.env, DOM elements typed too broadly, and catch errors — with proper fixes.

Property 'fullName' does not exist on type 'User'.

TypeScript knows the shape of User, and fullName isn't in it. Either the property really doesn't exist (a bug), or the type doesn't describe the data correctly. (What is TypeScript?)

Cause 1: a typo — or an invented property

user.fullname      // the type has fullName
user.full_name     // the API returns full_name, the type says fullName

Very common in AI-generated code: the model assumes a property exists because it sounds right. This error is TypeScript catching a hallucination before it reaches users. Check the real data (log it, or look at the API response in DevTools) and use the right name. (Why does AI hallucinate?)

Cause 2: the type is incomplete

The data really has the property, but your type doesn't list it. Add it:

type User = {
  id: string
  email: string
  fullName: string     // added
  avatarUrl?: string   // optional if not always present
}

If types are generated from your database (Prisma, Supabase, Drizzle), regenerate them after schema changes:

npx prisma generate
npx supabase gen types typescript --project-id <id> > types/supabase.ts

Cause 3: union types need narrowing

type Result = { ok: true; data: User } | { ok: false; error: string }

function show(r: Result) {
  console.log(r.data)    // ❌ Property 'data' does not exist on type '{ ok: false; error: string }'
}

r might be either shape. Check which one first:

if (r.ok) {
  console.log(r.data)    // ✅ TypeScript knows it's the success shape
} else {
  console.log(r.error)
}

Other ways to narrow: 'data' in r, typeof x === 'string', Array.isArray(x), x instanceof Date.

Cause 4: {}, object or unknown

const data: unknown = await res.json()
data.items     // ❌

unknown means "could be anything — check first". Validate it into a real type, ideally with a schema:

const Data = z.object({ items: z.array(z.object({ id: z.string() })) })
const data = Data.parse(await res.json())
data.items     // ✅ typed

(Validating input with Zod)

Cause 5: DOM elements typed too broadly

const input = document.getElementById('email')
input.value    // ❌ Property 'value' does not exist on type 'HTMLElement'

getElementById returns a generic HTMLElement (or null). Tell TypeScript which element it is:

const input = document.getElementById('email') as HTMLInputElement | null
if (input) console.log(input.value)

In React, type refs: useRef<HTMLInputElement>(null).

Cause 6: errors in catch blocks

try { ... } catch (err) {
  console.log(err.message)   // ❌ 'err' is of type 'unknown'
}

Anything can be thrown, so err is unknown:

catch (err) {
  const message = err instanceof Error ? err.message : String(err)
}

Cause 7: adding things to window or globals

window.analytics.track()   // ❌ Property 'analytics' does not exist on type 'Window'

Declare it once in a .d.ts file:

// global.d.ts
declare global {
  interface Window { analytics: { track(event: string): void } }
}
export {}

Cause 8: environment variable types

import.meta.env.VITE_API_URL errors in Vite projects without the type file. Add the declarations to src/vite-env.d.ts. (Environment variable undefined?)

What not to do

(user as any).fullName makes the error go away and leaves the bug. Fix the type or the property name instead. (Type is not assignable to type)


EasySpawn runs your TypeScript app with Claude Code on the same server, so it can check the real API response and fix the type instead of guessing. See how it works or join the waitlist.

Related: Type Is Not Assignable to Type · Object Is Possibly Undefined · JavaScript vs TypeScript · TypeScript Generics

Keep reading