Added AI skills

This commit is contained in:
Jose Selesan
2026-09-04 16:49:24 -03:00
parent 778f3fdcad
commit dfa7f73ebb
368 changed files with 51560 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
---
title: Use extend() for Adding Fields
impact: MEDIUM-HIGH
impactDescription: Merging objects manually loses type information; extend() preserves types and allows overriding fields safely
tags: object, extend, composition, inheritance
---
## Use extend() for Adding Fields
When building on existing schemas, use `.extend()` to add new fields rather than manually spreading. Extend preserves type information, allows overriding existing fields, and keeps the schema relationship explicit.
**Incorrect (manual object spreading):**
```typescript
import { z } from 'zod'
const baseUserSchema = z.object({
id: z.string(),
name: z.string(),
})
// Manual spreading loses Zod's schema relationship
const adminUserSchema = z.object({
...baseUserSchema.shape, // Accessing internal .shape
role: z.literal('admin'),
permissions: z.array(z.string()),
})
// Problems:
// 1. If baseUserSchema changes, TypeScript might not catch issues
// 2. Can't override fields easily
// 3. Loses schema methods and metadata
```
**Correct (using extend):**
```typescript
import { z } from 'zod'
const baseUserSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
})
// Extend to add fields
const adminUserSchema = baseUserSchema.extend({
role: z.literal('admin'),
permissions: z.array(z.string()),
})
type AdminUser = z.infer<typeof adminUserSchema>
// {
// id: string;
// name: string;
// email: string;
// role: 'admin';
// permissions: string[];
// }
// Override existing fields
const strictEmailSchema = baseUserSchema.extend({
email: z.string().email().endsWith('@company.com'), // Stricter validation
})
```
**Building hierarchies with extend:**
```typescript
// Base entity with common fields
const entitySchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
})
// User extends entity
const userSchema = entitySchema.extend({
email: z.string().email(),
name: z.string(),
})
// Product extends entity
const productSchema = entitySchema.extend({
name: z.string(),
price: z.number().positive(),
sku: z.string(),
})
// Order extends entity with references
const orderSchema = entitySchema.extend({
userId: z.string().uuid(),
items: z.array(z.object({
productId: z.string().uuid(),
quantity: z.number().int().positive(),
})),
total: z.number().positive(),
})
```
**Combining extend with other methods:**
```typescript
const baseSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string(),
})
// Create input: no id, add password
const createSchema = baseSchema
.omit({ id: true })
.extend({
password: z.string().min(8),
})
// Update input: all optional except id
const updateSchema = baseSchema
.partial()
.extend({
id: z.string(), // Override to make required
})
```
**Merge for combining independent schemas:**
```typescript
const addressSchema = z.object({
street: z.string(),
city: z.string(),
})
const contactSchema = z.object({
email: z.string().email(),
phone: z.string(),
})
// Merge combines two schemas (both required)
const customerSchema = addressSchema.merge(contactSchema)
// { street: string; city: string; email: string; phone: string }
```
**When NOT to use this pattern:**
- When schemas are genuinely independent (use merge or intersection)
- When you need to remove fields (use omit)
Reference: [Zod API - extend](https://zod.dev/api#extend)