@blakek/deep

中文文档
4.0.0发布于 2021/12/04MITTypeScriptESM + CJS近 30 天下载 14.5万

🐡 Get, set, remove, and test for deeply nested properties

原始使用文档
文档目录13 节
  1. Install
  2. Usage
  3. API
  4. clone
  5. get / createGetter
  6. has / createHas
  7. omit / createOmit
  8. pluck / createPluck
  9. remove / createRemove
  10. set / createSetter
  11. Contributing
  12. Useful Commands
  13. License

deep

🐡 Get, set, remove, and test for deeply nested properties

Helps you safely work with nested properties.

Install

Using Yarn:

$ yarn add @blakek/deep

…or using npm:

$ npm i --save @blakek/deep

Usage

import {
  clone,
  createGetter,
  get,
  has,
  omit,
  pluck,
  remove,
  set
  // also available:
  // - createHas
  // - createOmit
  // - createPluck
  // - createRemove
  // - createSetter
  // - isObject
  // - traverseObject
} from '@blakek/deep';

const user = {
  id: 'abf87de',
  roles: ['alert:create', 'alert:read'],
  sites: {
    github: {
      username: 'blakek'
    }
  }
};

// Deeply clone most values
const userCopy = clone(user);
user === userCopy; //» false
user.id === userCopy.id; //» true
user.roles === userCopy.roles; //» false
user.roles[0] === userCopy.roles[0]; //» true

// Get a property value
get('sites.github.username', user); //» 'blakek'

// Get a property value with a fallback other than `undefined`
get('sites.facebook.username', user, 'no-account'); //» 'no-account'

// Create a function to get a property value later
const getUsername = createGetter('sites.github.username');
getUsername(user); //» 'blakek'

// Test for a property value
has('sites.github', user); //» true

// Clone an object and omit properties
omit(['roles', 'sites'], user); //» { id: 'abf87de' }

// Pluck a subset of properties
pluck(['id', 'roles'], user);
//» { id: 'abf87de', roles: [ 'alert:create', 'alert:read' ] }

// Remove a property value, modifying the current object
remove('a', { a: 42, b: 123 }); //» { b: 123 }

// Set a property value, modifying the current object
set(123, 'a.b.c', { a: 42 }); //» { a: { b: { c: 123 } } }

API

For all these:

  • path can be either a dot-notation string or array of path parts

clone

Returns a deep clone / deep copy of most values: primitive values, objects, arrays, Map, Set, Date, etc.

function clone<T extends unknown>(value: T): T;
const object = { value: 'yep' };
const cloned = clone(object);

cloned === object; //» false
cloned.value === object.value; //» true

get / createGetter

Gets the value for a given path with an optional fallback value.

function get(path: Path, object: object, fallbackValue?: any): unknown;

function createGetter(
  path: Path,
  fallbackValue?: any
): (object: object) => unknown;
const user = {
  id: 'abf87de',
  roles: ['alert:create', 'alert:read'],
  sites: {
    github: {
      username: 'blakek'
    }
  }
};

get('id', user); //» 'abf87de'
get('roles.0', user); //» 'alert:create'
get('roles[0]', user); //» 'alert:create'
get(['roles', 1], user); //» 'alert:read'
get('sites.github.username', user); //» 'blakek'
get('sites.github.avatar.src', user, 'default.png'); //» 'default.png'

const getID = get('id');
getID(user); //» 'abf87de'

const getRoles = createGetter('roles');
getRoles(user); //» ['alert:create', 'alert:read']

has / createHas

Returns true if a value was found at the given path or false if nothing was found.

function has(path: Path, object: any): boolean;

function createHas(path: Path): (object: any) => boolean;
const product = {
  id: 'abf87de',
  name: 'Logo T-Shirt',
  attributes: {
    isCool: undefined,
    materials: ['cotton']
  }
};

has('attributes.materials', product); //» true
has(['avability', 'sizes'], product); //» false
has('attributes.isCool', product); //» true; property exists but is undefined

const hasMaterials = createHas('attributes.materials');
hasMaterials(product); //» true

// NOTE: `get()` should be used if you want to ensure a value is not `undefined`
get('attributes.isCool', product, false); //» false

omit / createOmit

Returns a clone of an object with a list of properties removed.

Note: omit() returns a clone with properties removed. If you'd rather modify the existing object for performance, consider using remove().

function omit(properties: Path[], object: any): any;

function createOmit(properties: Path[]): (object: any) => any;
const user = {
  username: 'blakek',
  roles: ['alert:create', 'alert:read'],
  sites: {
    github: {
      username: 'blakek'
    }
  }
};

omit(['roles', 'sites'], user); //» { username: 'blakek' }
omit(['username', 'roles', 'sites.doesnt.exist'], user);
//» { sites: { github: { username: 'blakek' } } }

const omitExtra = createOmit(['roles, sites']);
omitExtra(user); //» { username: 'blakek' }

pluck / createPluck

Gets a subset of properties from an object.

function pluck(properties: Path[], object: any): any;
const user = {
  username: 'blakek',
  roles: ['alert:create', 'alert:read'],
  sites: {
    github: {
      username: 'blakek'
    }
  }
};

pluck(['username'], user); //» { username: 'blakek' }
pluck(['username', 'roles'], user);
//» { username: 'blakek', roles: [ 'alert:create', 'alert:read' ] }

const permissionInfo = pluck(['roles', 'username']);
permissionInfo(user); //» { roles: [ 'alert:create', 'alert:read' ], username: 'blakek' }

remove / createRemove

Removes a value at a path and returns the object.

Note: remove() modifies the passed-in object rather than creating a copy. If you'd rather return a new object:

  • use omit(); omit() returns a clone with a list of properties removed
  • use clone() before remove()
  • consider another solution (unchanged is really good)
function remove(path: Path, object: any): any;

function createRemove(path: Path): (object: any) => any;
const user = {
  username: 'blakek',
  password: 'wouldntyouliketoknow'
};

remove('password', user); //» { username: 'blakek' }
remove('property.does.not.exist', user);
//» { username: 'blakek' } (same object from previous line)

const removePassword = createRemove('password');
removePassword({ username: 'bob', password: 'laskjfl' }); //» { username: 'bob' }

set / createSetter

Sets a value at a path and returns the object.

Note: set() modifies the passed-in object rather than creating a copy. If you'd rather return a new object:

  • use clone() before set()
  • consider another solution (unchanged is really good)
function set(value: any, path: Path, object: any): any;

function createSetter(path: Path, object: any): (value: any) => any;
const user = {
  profile: {
    bgColor: '#639'
  }
};

set('tomato', 'profile.bgColor', user); //» { profile: { bgColor: 'tomato' } }

set('/images/user.png', 'profile.bgImage', user);
//» { profile: { bgColor: 'tomato', bgImage: '/images/user.png' } }

const logout = set(null, 'profile');
logout(user); //» { profile: null }

const setUsername = createSetter('username', user);
setUsername('blakek'); //»  { profile: { bgColor: 'tomato', bgImage: '/images/user.png' }, username: 'blakek' }

Contributing

Node.js and Yarn are required to work with this project.

To install all dependencies, run:

yarn

Useful Commands

yarn buildBuilds the project to ./dist
yarn formatFormat the source following the Prettier styles
yarn testRun project tests
yarn test --watchRun project tests, watching for file changes

License

MIT

版本与发布记录

@blakek/deep 共发布 11 个版本,首次发布于 2020/06/02;过去 12 个月发布了 0 个版本。

版本发布日期距今
4.0.0latest2021/12/044 年前
3.0.02021/07/065 年前
2.2.02021/06/095 年前
2.1.12020/06/256 年前
2.1.02020/06/236 年前
2.0.12020/06/226 年前

关于 @blakek/deep 的常见问题

@blakek/deep 是什么?

🐡 Get, set, remove, and test for deeply nested properties

如何安装 @blakek/deep?

在项目目录运行 npm install @blakek/deep,或使用 pnpm add / yarn add / bun add。

@blakek/deep 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@blakek/deep 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@blakek/deep 可以商用吗?

@blakek/deep 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@blakek/deep 的下载量有多少?

根据 npm 官方下载统计,@blakek/deep 在 2026/10/09 – 2026/11/07 这 30 天内被下载 145,492 次,日均约 4,850 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@blakek/deep 还在维护吗?

最新版本 4.0.0 发布于 2021/12/04(4 年前);至今共发布 11 个版本,其中过去 12 个月发布了 0 个;首次发布于 2020/06/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。