Skip to content

set

Safely set nested properties of an object, supporting string paths and deep setting.

Basic Usage

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'

Syntax

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

Parameters

  • obj (T): The object to modify
  • path (string | string[]): The property path, which can be a string (dot-separated) or an array
  • value (any): The value to set

Return Value

Returns the modified new object, the original object is not modified.

Examples

Basic Property Setting

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'
// }

Nested Property Setting

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'
//   }
// }

Creating Deeply Nested

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'
//       }
//     }
//   }
// }

Using Array Paths

typescript
import { set } from 'radash'

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

// Using array paths
const updated = set(user, ['profile', 'address', 'country'], 'China')
console.log(updated.profile.address.country) // 'China'

Setting Array Elements

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']

Handling Complex Objects

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
// }

Updating API Responses

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)

Processing Form Data

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
}

// Simulate form 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'
//   }
// }

Updating Configuration Objects

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)

Handling Nested Arrays

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' }
// ]

Conditional Setting

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'

Batch Updates

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)

Handling Dynamic Paths

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'

Handling Complex Nested Structures

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']

Handling Different Types of Values

typescript
import { set } from 'radash'

const user = {
  name: 'Alice'
}

// Setting different types of values
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
// }

Handling Error Cases

typescript
import { set } from 'radash'

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

// Setting to null or undefined objects
const updated1 = set(user, 'address.country', 'China')
console.log(updated1.address.country) // 'China'

// Setting to non-existent paths
const updated2 = set(user, 'profile.email', 'alice@example.com')
console.log(updated2.profile.email) // 'alice@example.com'

// Setting to array index
const updated3 = set(user, 'hobbies.0', 'reading')
console.log(updated3.hobbies) // ['reading']

Notes

  1. Immutability: Returns a new object, does not modify the original object
  2. Path Format: Supports dot-separated string paths or array paths
  3. Deep Creation: Automatically creates non-existent nested paths
  4. Type Safety: Provides full TypeScript type support
  5. Performance: Good performance for deeply nested objects

Differences from Other Methods

  • obj.prop = value: Directly modifies the original object
  • lodash.set(): Similar functionality, but radash's set is lighter
  • set(): The immutable set method provided by radash

Practical Applications

  1. State Management: Immutablely update application state
  2. Form Processing: Dynamically update form data structure
  3. Configuration Management: Update nested settings in configuration files
  4. API Response Handling: Modify API response data structure
  5. Data Transformation: Build complex nested data structures

Released under the MIT License.