The error TypeError: undefined is not an object (Safari) or TypeError: Cannot read property 'x' of undefined (Chrome) occurs when trying to access properties or methods on undefined values. This is essentially the same as the "cannot read property" error but with Safari's wording.
// ⌠Problem
let user;
console.log(user.name); // TypeError: undefined is not an object
// ✅ Solution 1: Check if defined
if (user !== undefined) {
console.log(user.name);
}
// ✅ Solution 2: Optional chaining
console.log(user?.name); // undefined (no error)
// ✅ Solution 3: Default value
const name = user?.name || 'Guest';
Accessing properties on a variable that hasn't been assigned a value.
Function doesn't return a value, so accessing properties on the result fails.
Accessing an array index that doesn't exist returns undefined.
Accessing deeply nested properties when intermediate values are undefined.
Destructuring properties from undefined objects.
let user;
console.log(user.name); // TypeError: undefined is not an object
// Or declared but not initialized
let config;
console.log(config.apiUrl); // TypeError!
// Initialize with value
let user = { name: 'John', age: 30 };
console.log(user.name); // 'John'
// Or check before accessing
let user;
if (user) {
console.log(user.name);
}
// Use optional chaining
let user;
console.log(user?.name); // undefined (no error)
// Provide default value
let config;
const apiUrl = config?.apiUrl || 'https://api.example.com';
function getUser() {
// No return statement
const user = { name: 'John' };
}
const user = getUser(); // undefined
console.log(user.name); // TypeError: undefined is not an object
// Or conditional return
function findUser(id) {
if (id === 1) {
return { name: 'John' };
}
// No return for other IDs
}
const user = findUser(2); // undefined
console.log(user.name); // TypeError!
// Add return statement
function getUser() {
const user = { name: 'John' };
return user; // ✅
}
const user = getUser();
console.log(user.name); // 'John'
// Return default value for all paths
function findUser(id) {
if (id === 1) {
return { name: 'John' };
}
return null; // ✅ Explicit return
}
const user = findUser(2);
if (user) {
console.log(user.name);
}
// Or use optional chaining
const user = findUser(2);
console.log(user?.name); // undefined (no error)
const users = [
{ name: 'John' },
{ name: 'Jane' }
];
console.log(users[5].name); // TypeError: undefined is not an object
// Or with find()
const user = users.find(u => u.name === 'Bob'); // undefined
console.log(user.age); // TypeError!
const users = [
{ name: 'John' },
{ name: 'Jane' }
];
// Check array length
if (users.length > 5) {
console.log(users[5].name);
}
// Use optional chaining
console.log(users[5]?.name); // undefined (no error)
// Check find() result
const user = users.find(u => u.name === 'Bob');
if (user) {
console.log(user.age);
} else {
console.log('User not found');
}
// Or use optional chaining
const age = users.find(u => u.name === 'Bob')?.age;
const data = {
user: {
// profile is undefined
}
};
console.log(data.user.profile.name); // TypeError: undefined is not an object
// Or with API response
const response = {
data: {
// user is undefined
}
};
console.log(response.data.user.email); // TypeError!
// Use optional chaining for nested access
const data = {
user: {}
};
console.log(data?.user?.profile?.name); // undefined (no error)
// With default value
const name = data?.user?.profile?.name || 'Anonymous';
// Check each level
const data = {
user: {}
};
if (data && data.user && data.user.profile) {
console.log(data.user.profile.name);
}
// Initialize nested objects
const data = {
user: {
profile: {
name: 'John'
}
}
};
console.log(data.user.profile.name); // 'John'
function getUser() {
return undefined;
}
const { name, age } = getUser(); // TypeError: undefined is not an object
// Or with function parameters
function greet({ name }) {
console.log(`Hello ${name}`);
}
greet(); // TypeError: undefined is not an object
// Provide default value
function getUser() {
return undefined;
}
const { name, age } = getUser() || {}; // ✅ Default to empty object
// Or with nullish coalescing
const { name, age } = getUser() ?? {};
// Default parameter in function
function greet({ name } = {}) { // ✅ Default to empty object
console.log(`Hello ${name || 'Guest'}`);
}
greet(); // "Hello Guest"
// With default property values
function greet({ name = 'Guest' } = {}) {
console.log(`Hello ${name}`);
}
greet(); // "Hello Guest"
greet({ name: 'John' }); // "Hello John"
This error occurs when trying to access properties or methods on undefined values. Common causes include uninitialized variables, functions returning undefined, accessing non-existent array elements, or missing object properties.
Use optional chaining (?.), check if values exist before accessing properties, initialize variables properly, ensure functions return values, and provide default values in destructuring.
undefined means a variable has been declared but not assigned a value. null is an intentional absence of value. Both cause similar errors when accessing properties.
Optional chaining (?.) is an ES2020 feature that safely accesses nested properties. If any intermediate value is undefined/null, it returns undefined instead of throwing an error.
TypeScript's strict null checks catch undefined access at compile time. Enable strictNullChecks in tsconfig.json and properly type your variables to prevent this error.
Explore 500+ free tutorials across 20+ languages and frameworks.