Property does not exist on type

TypeScript can’t find that field on the type it has for this value, either because the type is wrong or because the value might not have it.

Editor, terminal, and build log
src/App.tsx:14:22 - error TS2339: Property 'title' does not exist on type 'Todo'.

Also appears as

  • Property 'title' does not exist on type 'never'.ts(2339)
  • ./src/app/page.tsx:14:22 Type error: Property 'title' does not exist on type 'Todo'.
  • error TS2339: Property 'env' does not exist on type 'ImportMeta'.
  • error TS2551: Property 'tite' does not exist on type 'Todo'. Did you mean 'title'?

Prompt to fix it

TypeScript reports "Property ... does not exist on type ..." (TS2339). For each error, find the type TypeScript infers for the value and why the property is missing from it. Fix the type at its source: give useState and other empty values an explicit type, narrow unions before reading fields, correct renamed fields, and regenerate database types if the schema changed. Don’t use as any, @ts-ignore, or @ts-expect-error to silence it. Run the project’s type check or build afterward to confirm no errors remain.

Paste into Layerwise or any AI coding tool.

What it means

TypeScript checks every value.property against the type it knows for value. TS2339 means that type has no property with that name. The page may still work in the browser, because the Vite and Next.js dev servers skip type checking. Builds don’t: next build, and Vite build scripts that run tsc, stop on it, which is why it often shows up first as a failed deploy.

The type never deserves a note. useState([]) with no type tells TypeScript the array will never hold anything, so todos[0].title fails. Other common shapes: 'value' does not exist on type 'EventTarget' from an event handler typed too loosely, 'env' does not exist on type 'ImportMeta' when Vite’s types aren’t loaded, and Supabase rows whose generated types are older than the database.

Casting with as any or adding // @ts-ignore hides the message and keeps the bug. If the property really might be missing, TypeScript is warning you about a crash like “Cannot read properties of undefined.” Give the value its real type, or check which shape you have before reading the field.

Common causes

  • A useState([]) without a type, so TypeScript infers never[] and no field exists on its items.
  • The value is a union, such as a success or error result, and the code reads a field only one side has.
  • Generated types are stale: the Supabase schema changed and the types weren’t regenerated.
  • A typo or a renamed field, such as user.fullName after the column became full_name.
  • Framework types aren’t loaded, like vite/client for import.meta.env in a Vite project.

How to fix it

  1. Hover over the value in your editor to see the type TypeScript has for it.
  2. If the type is never or too narrow, declare the real one, such as useState<Todo[]>([]).
  3. If it’s a union, narrow it first with a check like if ('error' in result) or if (user) before reading the field.
  4. If it comes from the database, regenerate the types with npx supabase gen types typescript --project-id <project-id> > src/database.types.ts.
  5. For import.meta.env in Vite, add "vite/client" to compilerOptions.types in tsconfig.app.json, or keep a src/vite-env.d.ts file containing /// <reference types="vite/client" />.
  6. Run npm run build locally to see every type error before you deploy.

Example fix

import { useState, type ChangeEvent } from 'react';

type Todo = { id: string; title: string };

export function TodoList() {
  // useState([]) alone infers never[], so todo.title would fail.
  const [todos, setTodos] = useState<Todo[]>([]);
  const [draft, setDraft] = useState('');

  // A typed event tells TypeScript that target is an input with a value.
  function handleChange(event: ChangeEvent<HTMLInputElement>) {
    setDraft(event.target.value);
  }

  function addTodo() {
    setTodos([...todos, { id: crypto.randomUUID(), title: draft }]);
  }

  return (
    <>
      <input value={draft} onChange={handleChange} />
      <button onClick={addTodo}>Add</button>
      {todos.map((todo) => <p key={todo.id}>{todo.title}</p>)}
    </>
  );
}
All errors
src/lib/stripe.ts:4:7 - error TS2322: Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.

Type is not assignable to type

A value’s type doesn’t match what the variable, prop, or function expects, often because the value might be missing or is the wrong kind.

TypeError: Cannot read properties of undefined (reading 'map')

Cannot read properties of undefined

The code asked for a property of a value that doesn’t exist yet, usually data that hasn’t loaded or a field the API didn’t return.

Error: Command "npm run build" exited with 1

Command "npm run build" exited with 1

Your build script failed on the host. This line only reports the failure; the actual error is printed earlier in the build log.

Error: Cannot find module 'express' Require stack: - /Users/me/my-app/server.js

Cannot find module

Node tried to load a package or file that isn’t where the code says it is, usually because it was never installed or the path is wrong.

Build with an agent that checks its work

The Layerwise agent clicks through the live preview and reads the console, so it catches errors before you do.