- Opt-in mutability with
remmi - Reference preservation (
merge(obj, { foo: true }) === obj) - Pipe-friendly (
pipe(merge({ foo: true })(obj)) - Graceful failure handling (
get(),getOr(),getOrElse(),getOrThrow())
npm install @monstermann/objectpnpm add @monstermann/objectyarn add @monstermann/objectbun add @monstermann/objectnpm install -D @monstermann/unplugin-objectpnpm -D add @monstermann/unplugin-objectyarn -D add @monstermann/unplugin-objectbun -D add @monstermann/unplugin-object// vite.config.tsimportobjectfrom"@monstermann/unplugin-object/vite";exportdefaultdefineConfig({plugins: [object()],});// rollup.config.jsimportobjectfrom"@monstermann/unplugin-object/rollup";exportdefault{plugins: [object()],};// rolldown.config.jsimportobjectfrom"@monstermann/unplugin-object/rolldown";exportdefault{plugins: [object()],};// webpack.config.jsconstobject=require("@monstermann/unplugin-object/webpack");module.exports={plugins: [object()],};// rspack.config.jsconstobject=require("@monstermann/unplugin-object/rspack");module.exports={plugins: [object()],};// esbuild.config.jsimport{build}from"esbuild";importobjectfrom"@monstermann/unplugin-object/esbuild";build({plugins: [object()],});functionObject.assign<Textendsobject,Uextendsobject>(target: T,source: U,): Textendsunknown ? Merge<T,U> : neverMerges properties from source object into target object, creating a new object.
Looser version of merge - assign allows you to redefine keys and add new properties.
import{Object}from"@monstermann/object";Object.assign({a: 1,b: 2},{b: 3,c: 4});// { a: 1, b: 3, c: 4 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.assign({b: 3,c: 4}));// { a: 1, b: 3, c: 4 }functionObject.clone<Textendsobject>(target: T): TCreates a shallow copy of an object, unless marked as mutable with markAsMutable inside a mutation context (see @monstermann/remmi).
import{Object}from"@monstermann/object";constoriginal={a: 1,b: 2};constcopy=Object.clone(original);// { a: 1, b: 2 }import{Object}from"@monstermann/object";constoriginal={a: 1,b: 2};constcopy=pipe(original,Object.clone());// { a: 1, b: 2 }functionObject.entries<Textendsobject>(target: T): Entries<T>Returns an array of key-value pairs from target object.
import{Object}from"@monstermann/object";Object.entries({a: 1,b: 2,c: 3});// [["a", 1], ["b", 2], ["c", 3]]import{Object}from"@monstermann/object";pipe({a: 1,b: 2,c: 3},Object.entries());// [["a", 1], ["b", 2], ["c", 3]]functionObject.evolve<Textendsobject,UextendsEvolver<T>>(target: T,evolver: U,): TCreates a new object with multiple properties transformed by their corresponding functions in the evolver object.
import{Object}from"@monstermann/object";Object.evolve({a: 1,b: 2,c: 3},{a: (x)=>x*2,c: (x)=>x+1,},);// { a: 2, b: 2, c: 4 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2,c: 3},Object.evolve({a: (x)=>x*2,c: (x)=>x+1,}),);// { a: 2, b: 2, c: 4 }functionObject.forEach<Textendsobject>(target: T,fn: ForEachCallback<T>,): TExecutes fn function for each key-value pair in target object and returns the original object.
import{Object}from"@monstermann/object";Object.forEach({a: 1,b: 2},([key,value])=>console.log(key,value));// { a: 1, b: 2 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.forEach(([key,value])=>console.log(key,value)),);// { a: 1, b: 2 }functionObject.fromEntries(): <constEntriesextendsIterableContainer<Entry>,>(entries: Entries,)=>Simplify<FromEntries<Entries>>Creates an object from an array of key-value pairs (entries). Each entry should be a tuple of [key, value].
import{Object}from"@monstermann/object";Object.fromEntries([["a",1],["b",2],["c",3],]);// { a: 1, b: 2, c: 3 }import{Object}from"@monstermann/object";pipe([["a",1],["b",2],["c",3],],Object.fromEntries(),);// { a: 1, b: 2, c: 3 }functionObject.get<Textendsobject,UextendskeyofAllUnionFields<T>,>(target: T,key: U): AllUnionFields<T>[U]Returns the value of key property from target object, or undefined if not found.
import{Object}from"@monstermann/object";Object.get({a: 1,b: 2},"a");// 1Object.get({a: 1,b: 2},"c");// undefinedimport{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.get("a"));// 1pipe({a: 1,b: 2},Object.get("c"));// undefinedfunctionObject.getOr<Textendsobject,UextendskeyofAllUnionFields<T>,V,>(target: T,key: U,or: V,): Exclude<AllUnionFields<T>[U]|V,null|undefined>Returns the value of key property from target object, or the or value if not found or nullish.
import{Object}from"@monstermann/object";Object.getOr({a: 1,b: 2},"a",0);// 1Object.getOr({a: 1,b: 2},"c",0);// 0import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.getOr("a",0));// 1pipe({a: 1,b: 2},Object.getOr("c",0));// 0functionObject.getOrElse<Textendsobject,UextendskeyofAllUnionFields<T>,V,>(target: T,key: U,orElse: (target: NoInfer<T>)=>V,): Exclude<AllUnionFields<T>[U]|V,null|undefined>Returns the value of key property from target object, or the result of calling orElse function with target if not found or nullish.
import{Object}from"@monstermann/object";Object.getOrElse({a: 1,b: 2},"a",()=>0);// 1Object.getOrElse({a: 1,b: 2},"c",(obj)=>Object.keys(obj).length);// 2import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.getOrElse("a",()=>0),);// 1pipe({a: 1,b: 2},Object.getOrElse("c",(obj)=>Object.keys(obj).length),);// 2functionObject.getOrThrow<Textendsobject,UextendskeyofAllUnionFields<T>,>(target: T,key: U,): Exclude<AllUnionFields<T>[U],null|undefined>Returns the value of key property from target object, or throws an error if not found or null/undefined.
import{Object}from"@monstermann/object";Object.getOrThrow({a: 1,b: 2},"a");// 1Object.getOrThrow({a: 1,b: 2},"c");// throws FnErrorimport{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.getOrThrow("a"));// 1pipe({a: 1,b: 2},Object.getOrThrow("c"));// throws FnErrorfunctionObject.hasKey<Textendsobject,UextendsKeysOfUnion<T>>(target: T,key: U,): target is HasKey<T,U>Checks if target object has the specified key property.
import{Object}from"@monstermann/object";Object.hasKey({a: 1,b: 2},"a");// trueObject.hasKey({a: 1,b: 2},"c");// falseimport{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.hasKey("a"));// truepipe({a: 1,b: 2},Object.hasKey("c"));// falsefunctionObject.hasProp<Textendsobject,UextendsKeysOfUnion<T>,>(target: T,key: U): target is HasProp<T,U>Checks if target object has the specified key property with a non-null and non-undefined value.
import{Object}from"@monstermann/object";Object.hasProp({a: 1,b: null},"a");// trueObject.hasProp({a: 1,b: null},"b");// falseimport{Object}from"@monstermann/object";pipe({a: 1,b: null},Object.hasProp("a"));// truepipe({a: 1,b: null},Object.hasProp("b"));// falsefunctionObject.is(target: unknown,): target is Record<PropertyKey,unknown>Checks if target is a plain object.
import{Object}from"@monstermann/object";Object.is({a: 1});// trueObject.is([]);// falseObject.is(null);// falseObject.is("hello");// falseimport{Object}from"@monstermann/object";pipe({a: 1},Object.is());// truepipe([],Object.is());// falsepipe(null,Object.is());// falsepipe("hello",Object.is());// falsefunctionObject.isEmpty<Textendsobject>(target: T): booleanChecks if target object has no enumerable properties.
import{Object}from"@monstermann/object";Object.isEmpty({});// trueObject.isEmpty({a: 1});// falseimport{Object}from"@monstermann/object";pipe({},Object.isEmpty());// truepipe({a: 1},Object.isEmpty());// falsefunctionObject.isShallowEqual<Textendsobject,UextendsT>(target: T,source: U,): target is UPerforms a shallow equality comparison between target and source objects.
import{Object}from"@monstermann/object";Object.isShallowEqual({a: 1,b: 2},{a: 1,b: 2});// trueObject.isShallowEqual({a: 1,b: 2},{a: 1,b: 3});// falseimport{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.isShallowEqual({a: 1,b: 2}));// truepipe({a: 1,b: 2},Object.isShallowEqual({a: 1,b: 3}));// falsefunctionObject.keys<Textendsobject>(target: T): KeysOfUnion<T>[]Returns an array of target object's enumerable property names.
import{Object}from"@monstermann/object";Object.keys({a: 1,b: 2,c: 3});// ["a", "b", "c"]import{Object}from"@monstermann/object";pipe({a: 1,b: 2,c: 3},Object.keys());// ["a", "b", "c"]functionObject.map<Textendsobject,UextendskeyofT>(target: T,key: U,transform: (value: NoInfer<T>[U])=>T[U],): TfunctionObject.map<Textendsobject,UextendskeyofT>(target: T,key: U,transform: (value: NoInfer<T>[U])=>T[U],): TCreates a new object with the key property transformed by the transform function.
import{Object}from"@monstermann/object";Object.map({a: 1,b: 2},"a",(x)=>x*2);// { a: 2, b: 2 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.map("a",(x)=>x*2),);// { a: 2, b: 2 }functionObject.mapAssign<Textendsobject,Uextendsobject>(target: T,map: (target: NoInfer<T>)=>U,): Textendsunknown ? Merge<T,U> : neverMerges target object with the result of calling map function on target, creating a new object.
Looser version of mapMerge - mapAssign allows you to redefine keys and add new properties.
import{Object}from"@monstermann/object";Object.mapAssign({a: 1,b: 2},(obj)=>({c: obj.a+obj.b}));// { a: 1, b: 2, c: 3 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.mapAssign((obj)=>({c: obj.a+obj.b})),);// { a: 1, b: 2, c: 3 }functionObject.mapMerge<Textendsobject>(target: T,map: (target: NoInfer<T>)=>Partial<NoInfer<T>>,): TMerges target object with the result of calling map function on target, creating a new object with existing keys updated.
import{Object}from"@monstermann/object";Object.mapMerge({a: 1,b: 2},(obj)=>({a: obj.a*2}));// { a: 2, b: 2 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.mapMerge((obj)=>({a: obj.a*2})),);// { a: 2, b: 2 }functionObject.matches<Textendsobject,UextendsT>(target: T,props: Partial<U>,): target is Matches<T,U>Checks if all properties in props object have equal values in target object.
import{Object}from"@monstermann/object";Object.matches({a: 1,b: 2,c: 3},{a: 1,b: 2});// trueObject.matches({a: 1,b: 2,c: 3},{a: 1,b: 3});// falseimport{Object}from"@monstermann/object";pipe({a: 1,b: 2,c: 3},Object.matches({a: 1,b: 2}));// truepipe({a: 1,b: 2,c: 3},Object.matches({a: 1,b: 3}));// falsefunctionObject.merge<Textendsobject>(target: T,source: Partial<NoInfer<T>>,): TMerges properties from source object into target object.
import{Object}from"@monstermann/object";Object.merge({a: 1,b: 2},{a: 3,c: 4});// { a: 3, b: 2 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.merge({a: 3,c: 4}));// { a: 3, b: 2 }functionObject.omit<Textendsobject,KextendsKeysOfUnion<T>>(target: T,keys: Iterable<K>,): DistributedOmit<T,K>Creates a new object excluding the properties specified in the keys iterable.
import{Object}from"@monstermann/object";Object.omit({a: 1,b: 2,c: 3},["a","c"]);// { b: 2 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2,c: 3},Object.omit(["a","c"]));// { b: 2 }functionObject.pick<Textendsobject,KextendsKeysOfUnion<T>>(target: T,keys: Iterable<K>,): DistributedPick<T,K>Creates a new object containing only the properties specified in the keys iterable.
import{Object}from"@monstermann/object";Object.pick({a: 1,b: 2,c: 3},["a","c"]);// { a: 1, c: 3 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2,c: 3},Object.pick(["a","c"]));// { a: 1, c: 3 }functionObject.propIs<Textendsobject,UextendskeyofAllUnionFields<T>,constVextendsAllUnionFields<T>[U],>(target: T,key: U,value: V): target is PropIs<T,U,V>Checks if the key property of target object is equal to the specified value using strict equality.
import{Object}from"@monstermann/object";Object.propIs({a: 1,b: 2},"a",1);// trueObject.propIs({a: 1,b: 2},"a",2);// falseimport{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.propIs("a",1));// truepipe({a: 1,b: 2},Object.propIs("a",2));// falsefunctionObject.set<Textendsobject,KextendskeyofT>(target: T,key: K,value: T[K],): TCreates a new object with the key property set to value.
import{Object}from"@monstermann/object";Object.set({a: 1,b: 2},"a",3);// { a: 3, b: 2 }import{Object}from"@monstermann/object";pipe({a: 1,b: 2},Object.set("a",3));// { a: 3, b: 2 }functionObject.test<Textendsobject,UextendskeyofAllUnionFields<T>,>(target: T,key: U,predicate: (value: AllUnionFields<T>[U])=>boolean,): target is Test<T,U,AllUnionFields<T>[U]>Checks if the key property of target object passes the predicate function test.
import{Object}from"@monstermann/object";Object.test({a: 5,b: 2},"a",(x)=>x>3);// trueObject.test({a: 1,b: 2},"a",(x)=>x>3);// falseimport{Object}from"@monstermann/object";pipe({a: 5,b: 2},Object.test("a",(x)=>x>3),);// truepipe({a: 1,b: 2},Object.test("a",(x)=>x>3),);// falsefunctionObject.testAll<Textendsobject,UextendsTestAllPredicates<T>,>(target: T,props: U): target is TestAllResult<T,U>Checks if all properties in target object pass their corresponding predicate functions in props object.
import{Object}from"@monstermann/object";Object.testAll({a: 5,b: 2},{a: (x)=>x>3,b: (x)=>x>0});// trueObject.testAll({a: 1,b: 2},{a: (x)=>x>3,b: (x)=>x>0});// falseimport{Object}from"@monstermann/object";pipe({a: 5,b: 2},Object.testAll({a: (x)=>x>3,b: (x)=>x>0}));// truepipe({a: 1,b: 2},Object.testAll({a: (x)=>x>3,b: (x)=>x>0}));// falsefunctionObject.values<Textendsobject>(target: T,): AllUnionFields<T>extends infer U ? U[keyofU][] : neverReturns an array of target object's enumerable property values.
import{Object}from"@monstermann/object";Object.values({a: 1,b: 2,c: 3});// [1, 2, 3]import{Object}from"@monstermann/object";pipe({a: 1,b: 2,c: 3},Object.values());// [1, 2, 3]