Nested Objects
Filter supports deep object filtering with intelligent TypeScript autocomplete up to 4 levels of nesting. This powerful feature allows you to query complex data structures with ease.
Overview
Nested object filtering enables you to:
- Filter by properties at any depth level
- Use operators on nested properties
- Get full TypeScript autocomplete for nested paths
- Combine nested filters with logical operators
- Handle complex data structures efficiently
Basic Nested Filtering
Simple Nested Property
interface User {
name: string;
address: {
city: string;
country: string;
};
}
const users: User[] = [
{ name: 'Alice', address: { city: 'Berlin', country: 'Germany' } },
{ name: 'Bob', address: { city: 'Paris', country: 'France' } },
{ name: 'Charlie', address: { city: 'Berlin', country: 'Germany' } },
];
filter(users, {
address: {
city: 'Berlin'
}
});Multiple Nested Properties
filter(users, {
address: {
city: 'Berlin',
country: 'Germany'
}
});Operators on Nested Properties
All operators work seamlessly with nested properties:
Comparison Operators
interface Product {
name: string;
pricing: {
amount: number;
currency: string;
};
}
const products: Product[] = [...];
filter(products, {
pricing: {
amount: { $gte: 100, $lte: 500 }
}
});String Operators
filter(users, {
address: {
city: { $startsWith: 'Ber' }
}
});Array Operators
interface Company {
name: string;
locations: {
offices: string[];
};
}
filter(companies, {
locations: {
offices: { $contains: 'Berlin' }
}
});Deep Nesting (Up to 4 Levels)
Filter supports up to 4 levels of nesting with full TypeScript support:
interface Organization {
name: string;
department: {
name: string;
team: {
name: string;
lead: {
name: string;
email: string;
};
};
};
}
const orgs: Organization[] = [...];
filter(orgs, {
department: {
team: {
lead: {
email: { $endsWith: '@company.com' }
}
}
}
});TypeScript Autocomplete
One of the most powerful features is intelligent autocomplete at every nesting level:
interface User {
profile: {
personal: {
age: number;
location: {
city: string;
};
};
};
}
filter(users, {
profile: {
personal: {
// TypeScript suggests: age, location
location: {
// TypeScript suggests: city
city: 'Berlin'
}
}
}
});Operator Autocomplete
TypeScript also suggests appropriate operators based on the property type:
filter(users, {
profile: {
personal: {
age: {
// TypeScript suggests: $gt, $gte, $lt, $lte, $eq, $ne, $in, $nin
$gte: 18
}
}
}
});Combining with Logical Operators
Nested Properties with $and
filter(users, {
$and: [
{
address: {
city: 'Berlin'
}
},
{
address: {
country: 'Germany'
}
}
]
});Nested Properties with $or
filter(users, {
$or: [
{
address: {
city: 'Berlin'
}
},
{
address: {
city: 'Paris'
}
}
]
});Complex Nested Logic
filter(users, {
$and: [
{
profile: {
personal: {
age: { $gte: 18 }
}
}
},
{
$or: [
{
address: {
city: 'Berlin'
}
},
{
address: {
country: 'France'
}
}
]
}
]
});Real-World Examples
E-commerce Order Filtering
interface Order {
id: string;
customer: {
name: string;
contact: {
email: string;
phone: string;
};
};
shipping: {
address: {
city: string;
country: string;
postalCode: string;
};
method: string;
};
payment: {
method: string;
status: string;
amount: number;
};
}
const orders: Order[] = [...];
filter(orders, {
shipping: {
address: {
country: 'Germany',
city: { $in: ['Berlin', 'Munich', 'Hamburg'] }
}
},
payment: {
status: 'completed',
amount: { $gte: 100 }
}
});User Profile Search
interface UserProfile {
username: string;
profile: {
bio: string;
social: {
twitter: string;
github: string;
};
preferences: {
theme: string;
notifications: {
email: boolean;
push: boolean;
};
};
};
}
filter(profiles, {
profile: {
social: {
github: { $startsWith: 'https://github.com/' }
},
preferences: {
notifications: {
email: true
}
}
}
});Organization Hierarchy
interface Organization {
name: string;
structure: {
department: {
name: string;
manager: {
name: string;
level: number;
};
budget: {
allocated: number;
spent: number;
};
};
};
}
filter(organizations, {
structure: {
department: {
manager: {
level: { $gte: 3 }
},
budget: {
spent: { $lt: 50000 }
}
}
}
});Configuration
Max Depth Control
Control the maximum nesting depth (default: 3):
filter(data, expression, {
maxDepth: 5
});This affects how deep the filter will traverse nested objects.
Performance Considerations
Best Practices
- Keep Nesting Reasonable: While 4 levels are supported, shallower structures are faster
- Use Specific Paths: More specific nested paths filter faster
- Index Critical Paths: For large datasets, consider pre-indexing nested properties
Performance Tips
filter(largeDataset, {
address: {
city: 'Berlin'
}
});For large datasets with frequent nested queries, consider:
- Enabling caching with
enableCache: true - Flattening deeply nested structures if possible
- Using lazy evaluation for early exits
Type Safety
Full TypeScript support ensures type-safe nested queries:
interface User {
profile: {
age: number;
};
}
filter(users, {
profile: {
age: 'invalid' // ❌ TypeScript error: Type 'string' is not assignable to type 'number'
}
});
filter(users, {
profile: {
age: { $gte: 18 } // ✅ Type-safe
}
});Limitations
- Maximum Depth: 4 levels of nesting
- Plain Objects Only: Arrays, Dates, and Functions are not traversed as nested objects
- Performance: Very deep nesting may impact performance on large datasets
Troubleshooting
Property Not Found
If nested properties aren't being matched:
const result = filterDebug(users, {
address: {
city: 'Berlin'
}
}, { verbose: true });
result.print();Type Errors
Ensure your interface matches your data structure:
interface User {
address?: {
city: string;
};
}Performance Issues
For slow nested queries:
- Enable caching
- Reduce nesting depth
- Use more specific filters
- Consider data structure optimization
Advanced Patterns
Partial Nested Matching
filter(users, {
address: {
city: 'Berlin'
}
});Combining Multiple Nested Paths
filter(users, {
profile: {
age: { $gte: 18 }
},
address: {
country: 'Germany'
}
});Nested Arrays with Objects
interface User {
orders: Array<{
items: Array<{
price: number;
}>;
}>;
}
filter(users, {
orders: {
items: {
price: { $gte: 100 }
}
}
});See Also
- Operators Guide - Available operators
- Logical Operators - Complex expressions
- Configuration - maxDepth and other options
- TypeScript Support - Type safety