Skip to content

set

安全地设置对象的嵌套属性值,支持路径字符串。

基础用法

typescript
import { set } from 'radash'

const user = {
  name: 'Alice',
  address: {
    city: 'Beijing'
  }
}

const updated = set(user, 'address.country', 'China')
console.log(updated.address.country) // 'China'

const updated2 = set(user, 'profile.email', 'alice@example.com')
console.log(updated2.profile.email) // 'alice@example.com'

语法

typescript
function set<T extends Record<string, any>>(
  obj: T,
  path: string | string[],
  value: any
): T

参数

  • obj (T): 要修改的对象
  • path (string | string[]): 属性路径,可以是字符串(用点分隔)或数组
  • value (any): 要设置的值

返回值

返回修改后的新对象,原对象不会被修改。

示例

基本属性设置

typescript
import { set } from 'radash'

const user = {
  name: 'Alice',
  age: 25
}

const updated = set(user, 'email', 'alice@example.com')
console.log(updated)
// {
//   name: 'Alice',
//   age: 25,
//   email: 'alice@example.com'
// }

嵌套属性设置

typescript
import { set } from 'radash'

const user = {
  name: 'Alice',
  address: {
    city: 'Beijing'
  }
}

const updated = set(user, 'address.country', 'China')
console.log(updated)
// {
//   name: 'Alice',
//   address: {
//     city: 'Beijing',
//     country: 'China'
//   }
// }

创建深层嵌套

typescript
import { set } from 'radash'

const user = {
  name: 'Alice'
}

const updated = set(user, 'profile.address.details.street', 'Main Street')
console.log(updated)
// {
//   name: 'Alice',
//   profile: {
//     address: {
//       details: {
//         street: 'Main Street'
//       }
//     }
//   }
// }

使用数组路径

typescript
import { set } from 'radash'

const user = {
  name: 'Alice',
  profile: {
    address: {
      city: 'Beijing'
    }
  }
}

// 使用数组路径
const updated = set(user, ['profile', 'address', 'country'], 'China')
console.log(updated.profile.address.country) // 'China'

设置数组元素

typescript
import { set } from 'radash'

const user = {
  name: 'Alice',
  hobbies: ['reading', 'swimming']
}

const updated = set(user, 'hobbies.2', 'coding')
console.log(updated.hobbies) // ['reading', 'swimming', 'coding']

const updated2 = set(user, 'hobbies.0', 'writing')
console.log(updated2.hobbies) // ['writing', 'swimming']

处理复杂对象

typescript
import { set } from 'radash'

const user = {
  id: 1,
  name: 'Alice',
  settings: {
    theme: 'light',
    notifications: {
      email: true
    }
  }
}

const updated = set(user, 'settings.notifications.push', false)
console.log(updated.settings.notifications)
// {
//   email: true,
//   push: false
// }

更新API响应

typescript
import { set } from 'radash'

function updateUserProfile(user: any, updates: Record<string, any>) {
  let updatedUser = user
  
  Object.entries(updates).forEach(([path, value]) => {
    updatedUser = set(updatedUser, path, value)
  })
  
  return updatedUser
}

const user = {
  id: 1,
  name: 'Alice',
  profile: {
    email: 'alice@example.com',
    address: {
      city: 'Beijing'
    }
  }
}

const updates = {
  'profile.email': 'alice.new@example.com',
  'profile.address.country': 'China',
  'profile.phone': '+86 123 4567 8900'
}

const updated = updateUserProfile(user, updates)
console.log(updated)

处理表单数据

typescript
import { set } from 'radash'

function processFormData(formData: FormData) {
  let data: any = {}
  
  for (const [key, value] of formData.entries()) {
    data = set(data, key, value)
  }
  
  return data
}

// 模拟表单数据
const mockFormData = new FormData()
mockFormData.append('user.firstName', 'Alice')
mockFormData.append('user.lastName', 'Smith')
mockFormData.append('user.email', 'alice@example.com')
mockFormData.append('address.street', '123 Main St')
mockFormData.append('address.city', 'Beijing')
mockFormData.append('preferences.newsletter', 'true')

const result = processFormData(mockFormData)
console.log(result)
// {
//   user: {
//     firstName: 'Alice',
//     lastName: 'Smith',
//     email: 'alice@example.com'
//   },
//   address: {
//     street: '123 Main St',
//     city: 'Beijing'
//   },
//   preferences: {
//     newsletter: 'true'
//   }
// }

更新配置对象

typescript
import { set } from 'radash'

function updateConfig(config: any, updates: Record<string, any>) {
  let updatedConfig = config
  
  Object.entries(updates).forEach(([path, value]) => {
    updatedConfig = set(updatedConfig, path, value)
  })
  
  return updatedConfig
}

const config = {
  server: {
    port: 3000,
    host: 'localhost'
  },
  database: {
    url: 'postgresql://localhost:5432/mydb'
  }
}

const updates = {
  'server.port': 8080,
  'server.timeout': 5000,
  'database.pool.min': 1,
  'database.pool.max': 10,
  'features.cache': true
}

const updated = updateConfig(config, updates)
console.log(updated)

处理嵌套数组

typescript
import { set } from 'radash'

const data = {
  departments: [
    {
      name: 'Engineering',
      employees: [
        { id: 1, name: 'Alice', role: 'Developer' }
      ]
    }
  ]
}

const updated = set(data, 'departments.0.employees.1', {
  id: 2,
  name: 'Bob',
  role: 'Manager'
})

console.log(updated.departments[0].employees)
// [
//   { id: 1, name: 'Alice', role: 'Developer' },
//   { id: 2, name: 'Bob', role: 'Manager' }
// ]

条件设置

typescript
import { set } from 'radash'

function setConditionalValue(obj: any, condition: boolean, path: string, trueValue: any, falseValue: any) {
  const value = condition ? trueValue : falseValue
  return set(obj, path, value)
}

const user = {
  name: 'Alice',
  isPremium: true
}

const updated = setConditionalValue(
  user,
  user.isPremium,
  'settings.theme',
  'dark',
  'light'
)

console.log(updated.settings.theme) // 'dark'

批量更新

typescript
import { set } from 'radash'

function batchSet(obj: any, updates: Array<{ path: string; value: any }>) {
  let result = obj
  
  updates.forEach(({ path, value }) => {
    result = set(result, path, value)
  })
  
  return result
}

const user = {
  name: 'Alice',
  profile: {
    email: 'alice@example.com'
  }
}

const updates = [
  { path: 'profile.phone', value: '+86 123 4567 8900' },
  { path: 'profile.address.city', value: 'Beijing' },
  { path: 'settings.theme', value: 'dark' },
  { path: 'settings.notifications', value: true }
]

const updated = batchSet(user, updates)
console.log(updated)

处理动态路径

typescript
import { set } from 'radash'

function setNestedValue(obj: any, pathParts: string[], value: any) {
  const path = pathParts.join('.')
  return set(obj, path, value)
}

const user = {
  name: 'Alice'
}

const updated = setNestedValue(user, ['profile', 'address', 'city'], 'Beijing')
console.log(updated.profile.address.city) // 'Beijing'

处理复杂嵌套结构

typescript
import { set } from 'radash'

const complexData = {
  company: {
    departments: [
      {
        name: 'Engineering',
        teams: [
          {
            name: 'Frontend',
            members: [
              { id: 1, name: 'Alice', skills: ['React'] }
            ]
          }
        ]
      }
    ]
  }
}

const updated = set(complexData, 'company.departments.0.teams.0.members.0.skills.1', 'TypeScript')
console.log(updated.company.departments[0].teams[0].members[0].skills)
// ['React', 'TypeScript']

处理不同类型值

typescript
import { set } from 'radash'

const user = {
  name: 'Alice'
}

// 设置不同类型的值
const updated1 = set(user, 'age', 25)
const updated2 = set(updated1, 'isActive', true)
const updated3 = set(updated2, 'tags', ['developer', 'frontend'])
const updated4 = set(updated3, 'settings', { theme: 'dark' })
const updated5 = set(updated4, 'lastLogin', null)

console.log(updated5)
// {
//   name: 'Alice',
//   age: 25,
//   isActive: true,
//   tags: ['developer', 'frontend'],
//   settings: { theme: 'dark' },
//   lastLogin: null
// }

处理错误情况

typescript
import { set } from 'radash'

const user = {
  name: 'Alice',
  address: {
    city: 'Beijing'
  }
}

// 设置到null或undefined对象
const updated1 = set(user, 'address.country', 'China')
console.log(updated1.address.country) // 'China'

// 设置到不存在的路径
const updated2 = set(user, 'profile.email', 'alice@example.com')
console.log(updated2.profile.email) // 'alice@example.com'

// 设置到数组索引
const updated3 = set(user, 'hobbies.0', 'reading')
console.log(updated3.hobbies) // ['reading']

注意事项

  1. 不可变性: 返回新对象,不修改原对象
  2. 路径格式: 支持点分隔的字符串路径或数组路径
  3. 深层创建: 自动创建不存在的嵌套路径
  4. 类型安全: 提供完整的TypeScript类型支持
  5. 性能: 对于深层嵌套对象,性能良好

与其他方法的区别

  • obj.prop = value: 直接修改原对象
  • lodash.set(): 类似功能,但radash的set更轻量
  • set(): radash提供的不可变设置方法

实际应用场景

  1. 状态管理: 不可变地更新应用状态
  2. 表单处理: 动态更新表单数据结构
  3. 配置管理: 更新配置文件中的嵌套设置
  4. API响应处理: 修改API响应数据结构
  5. 数据转换: 构建复杂的嵌套数据结构

Released under the MIT License.