Skip to content

/errors/typescript/ts2339-property-does-not-exist-on-type

error TS2339: Property 'email' does not exist on type 'User'

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · v24.20.0updated
tool
TypeScript
exit code
2
versions
TypeScript 5.x
os
any

error TS2339: Property 'email' does not exist on type 'User' means the TypeScript compiler looked up email on the declared type of the value and did not find it. The code may work at runtime (the object might really have that field), but the type does not say so. Add the property to the type, narrow the value to a type that has it, or fix the name. Casting to any silences the error and also removes every check on that value.

Reproduce it

bash
npm init -y >/dev/null
npm install --silent --no-audit --no-fund typescript@5 >/dev/null 2>&1
cat > app.ts <<'EOF'
interface User { id: number; name: string }
const user: User = { id: 1, name: "Ada" };
console.log(user.email);

const el = {} as object;
console.log(el.value);

window.myConfig = { debug: true };

type Shape = { kind: "circle"; radius: number } | { kind: "square"; side: number };
const area = (s: Shape) => Math.PI * s.radius ** 2;
EOF
npx tsc --noEmit --strict --pretty false --lib es2022,dom app.ts

Output · exit 2

app.ts(3,18): error TS2339: Property 'email' does not exist on type 'User'.
app.ts(6,16): error TS2339: Property 'value' does not exist on type 'object'.
app.ts(8,8): error TS2339: Property 'myConfig' does not exist on type 'Window & typeof globalThis'.
app.ts(11,40): error TS2339: Property 'radius' does not exist on type 'Shape'.
  Property 'radius' does not exist on type '{ kind: "square"; side: number; }'.

The message always names the declared type, which tells you where to look: User (your interface), object (a type too wide to have any property) Window & typeof globalThis (the browser global object) and Shape (a union where only one member has radius).

Fix it

bash
npm init -y >/dev/null
npm install --silent --no-audit --no-fund typescript@5 >/dev/null 2>&1
cat > globals.d.ts <<'EOF'
export {};
declare global {
  interface Window { myConfig?: { debug: boolean } }
}
EOF
cat > app.ts <<'EOF'
interface User { id: number; name: string; email?: string }   // 1. add the field
const user: User = { id: 1, name: "Ada" };
console.log(user.email ?? "no email");

function read(el: object) {
  if ("value" in el) console.log(el.value);                   // 2. narrow first
}
read({ value: 42 });

if (typeof window !== "undefined") window.myConfig = { debug: true };   // 3. declared in globals.d.ts
EOF
npx tsc --strict --pretty false --lib es2022,dom app.ts globals.d.ts && node app.js

Output

no email
42

Unions

On a union type, a property is only accessible if every member has it, and the error adds a second line naming the member that lacks it. Narrow with a discriminant field:

ts
type Shape = { kind: "circle"; radius: number } | { kind: "square"; side: number };

function area(s: Shape) {
  if (s.kind === "circle") return Math.PI * s.radius ** 2;
  return s.side ** 2;
}

Sources