mSet

mSet

  • (key: PropertyKey, value: any) => (anything: any) => anything
  1. Set a property

    Consider set instead.
    This is for the uncommon case where mutating anything is required.

    const obj = { a: 'b' }
    const setAToC = mSet('a', 'c')
    const mutatedObj = setAToC(obj)
    
    console.log(mutatedObj === obj) // is true
    console.log(obj) // is { a: 'c' }
    const obj = { a: 'b' }
    const setAToC = mSet('a', 'c')
    const mutatedObj = setAToC(obj)
    
    console.log(mutatedObj === obj) // is true
    console.log(obj) // is { a: 'c' }
    
    const obj = { a: 'b' }
    const setAToC = mSet('a', 'c')
    const mutatedObj = setAToC(obj)
    
    console.log(mutatedObj === obj) // is true
    console.log(obj) // is { a: 'c' }
    const obj = { a: 'b' }
    const setAToC = mSet('a', 'c')
    const mutatedObj = setAToC(obj)
    
    console.log(mutatedObj === obj) // is true
    console.log(obj) // is { a: 'c' }
    
  2. Sometimes we want to set a property. Below, we are building an array of cast members for True Detective Season 1. Let's add a property 'isLead' using the set of lead members.

    const topBilledCast = [
      { name: 'Matthew McConaughey' },
      { name: 'Woody Harrelson' },
      { name: 'Michelle Monaghan' },
      { name: 'Michael Potts' },
      { name: 'Tory Kittles' },
    ]
    
    const flagLead = mSet('isLead', true)
    const leads = new Set(['Matthew McConaughey', 'Woody Harrelson'])
    const isLead = actor => leads.has(actor.name)
    const flagAllLeads = compose([keepWhen(isLead), forEach(flagLead)])
    flagAllLeads(topBilledCast)
    
    console.log(topBilledCast)
    // is [
    //   { name: Matthew McConaughey, isLead: true }
    //   { name: Woody Harrelson, isLead: true }
    //   { name: Michelle Monaghan }
    //   { name: Michael Potts }
    //   { name: Tory Kittles }
    // ]
    type Actor = {
      name: string
      isLead?: true
    }
    const topBilledCast: Actor[] = [
      { name: 'Matthew McConaughey' },
      { name: 'Woody Harrelson' },
      { name: 'Michelle Monaghan' },
      { name: 'Michael Potts' },
      { name: 'Tory Kittles' },
    ]
    
    const flagLead = mSet('isLead', true)<Actor>
    const leads = new Set(['Matthew McConaughey', 'Woody Harrelson'])
    const isLead = (actor: Actor) => leads.has(actor.name)
    const flagAllLeads = compose([
      keepWhen(isLead)<Actor[]>,
      forEach(flagLead)<Actor[]>,
    ])
    flagAllLeads(topBilledCast)
    
    console.log(topBilledCast)
    // is [
    //   { name: Matthew McConaughey, isLead: true }
    //   { name: Woody Harrelson, isLead: true }
    //   { name: Michelle Monaghan }
    //   { name: Michael Potts }
    //   { name: Tory Kittles }
    // ]
    
    const topBilledCast = [
      { name: 'Matthew McConaughey' },
      { name: 'Woody Harrelson' },
      { name: 'Michelle Monaghan' },
      { name: 'Michael Potts' },
      { name: 'Tory Kittles' },
    ]
    
    const flagLead = mSet('isLead', true)
    const leads = new Set([
      'Matthew McConaughey',
      'Woody Harrelson',
    ])
    const isLead = actor => leads.has(actor.name)
    const flagAllLeads = compose([
      keepWhen(isLead),
      forEach(flagLead),
    ])
    flagAllLeads(topBilledCast)
    
    console.log(topBilledCast)
    // is [
    //   { name: Matthew McConaughey, isLead: true }
    //   { name: Woody Harrelson, isLead: true }
    //   { name: Michelle Monaghan }
    //   { name: Michael Potts }
    //   { name: Tory Kittles }
    // ]
    type Actor = {
      name: string
      isLead?: true
    }
    const topBilledCast: Actor[] = [
      { name: 'Matthew McConaughey' },
      { name: 'Woody Harrelson' },
      { name: 'Michelle Monaghan' },
      { name: 'Michael Potts' },
      { name: 'Tory Kittles' },
    ]
    
    const flagLead = mSet('isLead', true)<Actor>
    const leads = new Set([
      'Matthew McConaughey',
      'Woody Harrelson',
    ])
    const isLead = (actor: Actor) =>
      leads.has(actor.name)
    const flagAllLeads = compose([
      keepWhen(isLead)<Actor[]>,
      forEach(flagLead)<Actor[]>,
    ])
    flagAllLeads(topBilledCast)
    
    console.log(topBilledCast)
    // is [
    //   { name: Matthew McConaughey, isLead: true }
    //   { name: Woody Harrelson, isLead: true }
    //   { name: Michelle Monaghan }
    //   { name: Michael Potts }
    //   { name: Tory Kittles }
    // ]
    
  3. This utility requires the key be assignable on anything

    The example shows the error thrown

    const setAToC = mSet('a', 'c')
    try {
      setAToC(1)
    } catch (err) {
      console.log(err)
      // prints
      // 'mSet requires key to be assignable.  See error properties for more info.'
    }
    const setAToC = mSet('a', 'c')
    const obj = {}
    Object.defineProperty(obj, 'a', {
      enumerable: true,
      writable: false,
      value: 'b',
    })
    try {
      setAToC(obj)
    } catch (err) {
      console.log(err)
      // prints
      // 'mSet requires key to be assignable.  See error properties for more info.'
    }
    
    const setAToC = mSet('a', 'c')
    try {
      setAToC(1)
    } catch (err) {
      console.log(err)
      // prints
      // 'mSet requires key to be assignable.  See
      // error properties for more info.'
    }
    const setAToC = mSet('a', 'c')
    const obj = {}
    Object.defineProperty(obj, 'a', {
      enumerable: true,
      writable: false,
      value: 'b',
    })
    try {
      setAToC(obj)
    } catch (err) {
      console.log(err)
      // prints
      // 'mSet requires key to be assignable.  See
      // error properties for more info.'
    }