npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kne/is-empty

v1.1.0

Published

用于判断和过滤空值的工具库,支持对象、数组的递归判断,保留数字0和布尔值false

Readme

is-empty

描述

用于判断和过滤空值的工具库,支持对象、数组的递归判断,保留数字0和布尔值false

安装

npm i --save @kne/is-empty

概述

用于判断数据是否为空,考虑了数组和对象的情况。

核心特性

  • isNotEmpty: 判断值是否为非空,支持对象、数组、字符串、数字等多种类型
  • isEmpty: 判断值是否为空,是 isNotEmpty 的反向函数
  • filterEmpty: 递归过滤对象或数组中的空值,常用于表单数据处理

判断规则

对象类型

对象需要有至少一个属性的值为真值才被视为非空,判断会递归进行:

isNotEmpty({});                    // false - 空对象
isNotEmpty({ a: null });           // false - 属性值为假值
isNotEmpty({ a: 1 });              // true - 有真值属性
isNotEmpty({ a: { b: 1 } });       // true - 嵌套对象有真值
isNotEmpty({ a: { b: null } });    // false - 嵌套对象无真值

数组类型

数组需要有至少一个元素的值为真值才被视为非空:

isNotEmpty([]);                    // false - 空数组
isNotEmpty([null]);                // false - 元素为假值
isNotEmpty([1]);                   // true - 有真值元素
isNotEmpty([null, 1]);             // true - 有真值元素

其他类型

| 类型 | 非空条件 | |----------------|----------------------| | 数字 | 有效数字(非 NaN),0 也是非空 | | 字符串 | 非空字符串,空格也是非空 | | boolean | 始终为非空,false 也是非空 | | null/undefined | 始终为空 |

使用场景

  • 表单数据验证和清理
  • API 请求参数过滤
  • 条件渲染判断
  • 数据清洗和处理

示例

示例代码

  • 基础用法
  • 展示 isEmpty、isNotEmpty、filterEmpty 的基本使用方法
  • _IsEmpty(@kne/current-lib_is-empty)[import * as _IsEmpty from "@kne/is-empty"],antd(antd)
const { isEmpty, isNotEmpty, filterEmpty } = _IsEmpty;
const { Flex, Typography, Card, Descriptions } = antd;
const { Text, Title } = Typography;

const BaseExample = () => {
  return (
    <Flex vertical gap={24}>
      <Card title="isEmpty 示例" size="small">
        <Descriptions column={1} size="small">
          <Descriptions.Item label="isEmpty({})">{isEmpty({}).toString()}</Descriptions.Item>
          <Descriptions.Item label="isEmpty({ a: 1 })">{isEmpty({ a: 1 }).toString()}</Descriptions.Item>
          <Descriptions.Item label="isEmpty([])">{isEmpty([]).toString()}</Descriptions.Item>
          <Descriptions.Item label="isEmpty([1])">{isEmpty([1]).toString()}</Descriptions.Item>
          <Descriptions.Item label="isEmpty(null)">{isEmpty(null).toString()}</Descriptions.Item>
          <Descriptions.Item label="isEmpty('')">{isEmpty('').toString()}</Descriptions.Item>
          <Descriptions.Item label="isEmpty(0)">{isEmpty(0).toString()}</Descriptions.Item>
          <Descriptions.Item label="isEmpty(NaN)">{isEmpty(NaN).toString()}</Descriptions.Item>
        </Descriptions>
      </Card>

      <Card title="isNotEmpty 示例" size="small">
        <Descriptions column={1} size="small">
          <Descriptions.Item label="isNotEmpty({})">{isNotEmpty({}).toString()}</Descriptions.Item>
          <Descriptions.Item label="isNotEmpty({ a: 1 })">{isNotEmpty({ a: 1 }).toString()}</Descriptions.Item>
          <Descriptions.Item label="isNotEmpty([])">{isNotEmpty([]).toString()}</Descriptions.Item>
          <Descriptions.Item label="isNotEmpty([1])">{isNotEmpty([1]).toString()}</Descriptions.Item>
          <Descriptions.Item label="isNotEmpty(null)">{isNotEmpty(null).toString()}</Descriptions.Item>
          <Descriptions.Item label="isNotEmpty('')">{isNotEmpty('').toString()}</Descriptions.Item>
          <Descriptions.Item label="isNotEmpty(0)">{isNotEmpty(0).toString()}</Descriptions.Item>
          <Descriptions.Item label="isNotEmpty('text')">{isNotEmpty('text').toString()}</Descriptions.Item>
        </Descriptions>
      </Card>

      <Card title="filterEmpty 示例" size="small">
        <Flex vertical gap={8}>
          <Text code>{"filterEmpty({ a: 1, b: null, c: undefined, d: '', e: 'text' })"}</Text>
          <Text>{JSON.stringify(filterEmpty({ a: 1, b: null, c: undefined, d: '', e: 'text' }))}</Text>
        </Flex>
      </Card>
    </Flex>
  );
};

render(<BaseExample />);
  • isNotEmpty 判断非空
  • isNotEmpty 函数用于判断值是否为非空,支持对象、数组、字符串等多种类型
  • _IsEmpty(@kne/current-lib_is-empty)[import * as _IsEmpty from "@kne/is-empty"],antd(antd)
const { isNotEmpty } = _IsEmpty;
const { Flex, Typography, Card, Table, Tag, Divider } = antd;
const { Text, Title } = Typography;

const IsNotEmptyExample = () => {
  const testCases = [
    // 对象类型
    { category: '对象类型', value: {}, description: '空对象', expected: false },
    { category: '对象类型', value: { a: null, b: undefined, c: '' }, description: '所有属性为假值', expected: false },
    { category: '对象类型', value: { a: 1 }, description: '有真值属性', expected: true },
    { category: '对象类型', value: { a: null, b: 1 }, description: '部分属性为真值', expected: true },
    { category: '对象类型', value: { a: false, b: true }, description: 'boolean 属性', expected: true },

    // 数组类型
    { category: '数组类型', value: [], description: '空数组', expected: false },
    { category: '数组类型', value: [1], description: '非空数组', expected: true },
    { category: '数组类型', value: [null], description: '仅包含 null', expected: false },
    { category: '数组类型', value: [undefined], description: '仅包含 undefined', expected: false },
    { category: '数组类型', value: [null, 1], description: '包含真值元素', expected: true },

    // 数字类型
    { category: '数字类型', value: 0, description: '数字 0', expected: true },
    { category: '数字类型', value: 1, description: '正整数', expected: true },
    { category: '数字类型', value: -1, description: '负整数', expected: true },
    { category: '数字类型', value: NaN, description: 'NaN', expected: false },

    // 字符串类型
    { category: '字符串类型', value: '', description: '空字符串', expected: false },
    { category: '字符串类型', value: 'text', description: '非空字符串', expected: true },
    { category: '字符串类型', value: ' ', description: '空格字符串', expected: true },

    // 其他类型
    { category: '其他类型', value: null, description: 'null', expected: false },
    { category: '其他类型', value: undefined, description: 'undefined', expected: false },
    { category: '其他类型', value: true, description: 'boolean true', expected: true },
    { category: '其他类型', value: false, description: 'boolean false', expected: true },
  ];

  const columns = [
    {
      title: '类型',
      dataIndex: 'category',
      key: 'category',
      width: 120,
    },
    {
      title: '值',
      dataIndex: 'value',
      key: 'value',
      width: 200,
      render: (value) => <Text code>{JSON.stringify(value)}</Text>
    },
    {
      title: '说明',
      dataIndex: 'description',
      key: 'description',
      width: 150,
    },
    {
      title: '预期结果',
      dataIndex: 'expected',
      key: 'expected',
      width: 100,
      render: (expected) => (
        <Tag color={expected ? 'green' : 'red'}>
          {expected ? 'true' : 'false'}
        </Tag>
      )
    },
    {
      title: '实际结果',
      key: 'actual',
      width: 100,
      render: (_, record) => {
        const result = isNotEmpty(record.value);
        const isCorrect = result === record.expected;
        return (
          <Tag color={isCorrect ? 'green' : 'red'}>
            {result.toString()}
          </Tag>
        );
      }
    },
  ];

  return (
    <Flex vertical gap={16}>
      <Card size="small">
        <Text>
          <Text strong>isNotEmpty</Text> 用于判断值是否为非空。
          对于对象,需要至少有一个真值属性才返回 true;
          对于数组,需要至少有一个真值元素才返回 true。
        </Text>
      </Card>
      <Table
        columns={columns}
        dataSource={testCases}
        rowKey={(record, index) => index}
        pagination={false}
        size="small"
      />
    </Flex>
  );
};

render(<IsNotEmptyExample />);
  • isEmpty 判断为空
  • isEmpty 函数是 isNotEmpty 的反向,用于判断值是否为空
  • _IsEmpty(@kne/current-lib_is-empty)[import * as _IsEmpty from "@kne/is-empty"],antd(antd)
const { isEmpty } = _IsEmpty;
const { Flex, Typography, Card, Table, Tag, Divider } = antd;
const { Text, Title } = Typography;

const IsEmptyExample = () => {
  const testCases = [
    // 对象类型
    { category: '对象类型', value: {}, description: '空对象', expected: true },
    { category: '对象类型', value: { a: null, b: undefined, c: '' }, description: '所有属性为假值', expected: true },
    { category: '对象类型', value: { a: 1 }, description: '有真值属性', expected: false },

    // 数组类型
    { category: '数组类型', value: [], description: '空数组', expected: true },
    { category: '数组类型', value: [1], description: '非空数组', expected: false },
    { category: '数组类型', value: [null], description: '仅包含 null', expected: true },

    // 数字类型
    { category: '数字类型', value: 0, description: '数字 0', expected: false },
    { category: '数字类型', value: NaN, description: 'NaN', expected: true },

    // 字符串类型
    { category: '字符串类型', value: '', description: '空字符串', expected: true },
    { category: '字符串类型', value: 'text', description: '非空字符串', expected: false },

    // 其他类型
    { category: '其他类型', value: null, description: 'null', expected: true },
    { category: '其他类型', value: undefined, description: 'undefined', expected: true },
    { category: '其他类型', value: true, description: 'boolean true', expected: false },
    { category: '其他类型', value: false, description: 'boolean false', expected: false },
  ];

  const columns = [
    {
      title: '类型',
      dataIndex: 'category',
      key: 'category',
      width: 120,
    },
    {
      title: '值',
      dataIndex: 'value',
      key: 'value',
      width: 200,
      render: (value) => <Text code>{JSON.stringify(value)}</Text>
    },
    {
      title: '说明',
      dataIndex: 'description',
      key: 'description',
      width: 150,
    },
    {
      title: '预期结果',
      dataIndex: 'expected',
      key: 'expected',
      width: 100,
      render: (expected) => (
        <Tag color={expected ? 'green' : 'red'}>
          {expected ? 'true' : 'false'}
        </Tag>
      )
    },
    {
      title: '实际结果',
      key: 'actual',
      width: 100,
      render: (_, record) => {
        const result = isEmpty(record.value);
        const isCorrect = result === record.expected;
        return (
          <Tag color={isCorrect ? 'green' : 'red'}>
            {result.toString()}
          </Tag>
        );
      }
    },
  ];

  return (
    <Flex vertical gap={16}>
      <Card size="small">
        <Text>
          <Text strong>isEmpty</Text> 是 <Text strong>isNotEmpty</Text> 的反向函数,
          用于判断值是否为空。两个函数结果互为相反。
        </Text>
      </Card>
      <Table
        columns={columns}
        dataSource={testCases}
        rowKey={(record, index) => index}
        pagination={false}
        size="small"
      />
    </Flex>
  );
};

render(<IsEmptyExample />);
  • filterEmpty 过滤空值
  • filterEmpty 函数用于递归过滤对象或数组中的空值,常用于表单数据处理
  • _IsEmpty(@kne/current-lib_is-empty)[import * as _IsEmpty from "@kne/is-empty"],antd(antd)
const { filterEmpty, isNotEmpty } = _IsEmpty;
const { Flex, Typography, Card, Divider, Input, Form, Button, Space, message } = antd;
const { Text, Title, Paragraph } = Typography;
const { useState } = React;

const FilterEmptyExample = () => {
  // 模拟表单数据
  const [formData, setFormData] = useState({
    name: '张三',
    age: null,
    email: '',
    phone: '13800138000',
    address: {
      province: '北京市',
      city: null,
      district: '',
      detail: '朝阳区xxx街道'
    },
    tags: ['标签1', null, '标签2', ''],
    attachments: [],
    remark: undefined
  });

  const handleFilter = () => {
    const filtered = filterEmpty(formData);
    message.success('过滤完成,请查看控制台');
    console.log('原始数据:', formData);
    console.log('过滤后数据:', filtered);
  };

  // 递归过滤示例
  const nestedExample = {
    level1: {
      level2: {
        validData: { x: 0, y: 0 },
        emptyObj: {},
        nullValue: null
      },
      emptyArray: []
    },
    items: [
      { id: 1, name: '项目1', desc: null },
      { id: 2, name: '', desc: '描述2' },
      null,
      { id: 3, name: '项目3', desc: '' }
    ]
  };

  const filteredNested = filterEmpty(nestedExample);

  return (
    <Flex vertical gap={24}>
      <Card title="对象过滤" size="small">
        <Flex vertical gap={12}>
          <Text strong>原始对象:</Text>
          <Paragraph code style={{ marginBottom: 8 }}>
            {JSON.stringify(formData, null, 2)}
          </Paragraph>
          <Divider style={{ margin: '8px 0' }} />
          <Text strong>过滤后对象:</Text>
          <Paragraph code style={{ marginBottom: 8 }}>
            {JSON.stringify(filterEmpty(formData), null, 2)}
          </Paragraph>
          <Text type="secondary">
            注意:null、undefined、空字符串被过滤,数字 0 和 false 被保留
          </Text>
        </Flex>
      </Card>

      <Card title="数组过滤" size="small">
        <Flex vertical gap={12}>
          <Text strong>原始数组:</Text>
          <Text code>{JSON.stringify([1, null, 2, undefined, '', 3])}</Text>
          <Text strong>过滤后数组:</Text>
          <Text code>{JSON.stringify(filterEmpty([1, null, 2, undefined, '', 3]))}</Text>
        </Flex>
      </Card>

      <Card title="递归过滤嵌套结构" size="small">
        <Flex vertical gap={12}>
          <Text strong>原始数据:</Text>
          <Paragraph code style={{ marginBottom: 8, fontSize: 12 }}>
            {JSON.stringify(nestedExample, null, 2)}
          </Paragraph>
          <Divider style={{ margin: '8px 0' }} />
          <Text strong>过滤后数据:</Text>
          <Paragraph code style={{ marginBottom: 8, fontSize: 12 }}>
            {JSON.stringify(filteredNested, null, 2)}
          </Paragraph>
          <Text type="secondary">
            递归过滤会处理所有嵌套的对象和数组,空对象和空数组在过滤后如果变为空也会被移除
          </Text>
        </Flex>
      </Card>

      <Card title="特殊值处理" size="small">
        <Flex vertical gap={8}>
          <Text>数字 0 处理:</Text>
          <Text code>{'filterEmpty({ a: 0, b: null }) → ' + JSON.stringify(filterEmpty({ a: 0, b: null }))}</Text>
          <Divider style={{ margin: '8px 0' }} />
          <Text>布尔值 false 处理:</Text>
          <Text code>{'filterEmpty({ a: false, b: null }) → ' + JSON.stringify(filterEmpty({ a: false, b: null }))}</Text>
          <Divider style={{ margin: '8px 0' }} />
          <Text>空对象过滤:</Text>
          <Text code>{'filterEmpty({ nested: {} }) → ' + JSON.stringify(filterEmpty({ nested: {} }))}</Text>
        </Flex>
      </Card>

      <Card title="使用场景 - 表单提交前清理" size="small">
        <Text type="secondary">
          在表单提交前,使用 filterEmpty 清理掉用户未填写的字段,避免提交大量空值到后端。
        </Text>
        <Flex style={{ marginTop: 12 }}>
          <Button type="primary" onClick={handleFilter}>
            模拟提交(查看控制台)
          </Button>
        </Flex>
      </Card>
    </Flex>
  );
};

render(<FilterEmptyExample />);

API

isNotEmpty

function isNotEmpty(value: any): boolean

参数

| 参数 | 类型 | 说明 | |------|------|------| | value | any | 需要判断的值 |

返回值

返回 boolean,表示值是否为非空。

判断规则

| 类型 | 非空条件 | |------|----------| | 对象 | 至少有一个属性的值为真值(递归判断) | | 数组 | 至少有一个元素的值为真值(递归判断) | | 数字 | 有效数字(非 NaN) | | 字符串 | 非空字符串 | | boolean | 始终返回 true | | null/undefined | 返回 false |

示例

import { isNotEmpty } from '@kne/is-empty';

isNotEmpty({});                    // false
isNotEmpty({ a: 1 });              // true
isNotEmpty({ a: null, b: 1 });     // true
isNotEmpty([]);                    // false
isNotEmpty([1]);                   // true
isNotEmpty([null]);                // false
isNotEmpty(0);                     // true
isNotEmpty(NaN);                   // false
isNotEmpty('');                    // false
isNotEmpty('text');                // true
isNotEmpty(null);                  // false
isNotEmpty(undefined);             // false
isNotEmpty(true);                  // true
isNotEmpty(false);                 // true

isEmpty

判断值是否为空,是 isNotEmpty 的反向函数。

函数签名

function isEmpty(value: any): boolean

参数

| 参数 | 类型 | 说明 | |------|------|------| | value | any | 需要判断的值 |

返回值

返回 boolean,表示值是否为空。

示例

import { isEmpty } from '@kne/is-empty';

isEmpty({});           // true
isEmpty({ a: 1 });     // false
isEmpty([]);           // true
isEmpty([1]);          // false
isEmpty('');           // true
isEmpty('text');       // false
isEmpty(0);            // false
isEmpty(NaN);          // true
isEmpty(null);         // true
isEmpty(undefined);    // true

filterEmpty

递归过滤对象或数组中的空值。

函数签名

function filterEmpty(value?: object | array): object | array | any

参数

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | value | object | array | {} | 需要过滤的值 |

返回值

返回过滤后的值,空对象和空数组会被移除。

过滤规则

以下值会被过滤:

  • null
  • undefined
  • 空字符串 ''
  • 空对象 {}
  • 空数组 []
  • 仅包含上述空值的对象或数组

以下值会被保留:

  • 数字 0
  • 布尔值 false
  • 非空字符串
  • 非空对象
  • 非空数组

示例

import { filterEmpty } from '@kne/is-empty';

// 过滤对象中的空值
filterEmpty({ a: 1, b: null, c: undefined, d: '', e: 'text' });
// 返回: { a: 1, e: 'text' }

// 过滤数组中的空值
filterEmpty([1, null, 2, undefined, '', 3]);
// 返回: [1, 2, 3]

// 递归过滤嵌套对象
filterEmpty({
  a: { b: null, c: 1 },
  d: { e: '' }
});
// 返回: { a: { c: 1 } }

// 递归过滤嵌套数组
filterEmpty([{ a: 1, b: null }, { c: '', d: 2 }, null]);
// 返回: [{ a: 1 }, { d: 2 }]

// 保留数字 0
filterEmpty({ a: 0, b: null });
// 返回: { a: 0 }

// 保留布尔值 false
filterEmpty({ a: false, b: null });
// 返回: { a: false }

// 无参数调用
filterEmpty();
// 返回: {}