Skip to content

shake

移除對象中的空值(null、undefined、空字符串、空數組、空對象),返回清理後的新對象。

基礎用法

typescript
import { shake } from 'radash'

const obj = {
  name: 'Alice',
  age: 25,
  email: '',
  address: null,
  hobbies: [],
  settings: {}
}

const cleaned = shake(obj)
console.log(cleaned) // { name: 'Alice', age: 25 }

語法

typescript
function shake<T extends Record<string, any>>(obj: T): Partial<T>

參數

  • obj (T): 要清理的對象

返回值

返回清理後的新對象,移除所有空值。

示例

基本清理

typescript
import { shake } from 'radash'

const obj = {
  name: 'Alice',
  age: 25,
  email: '',
  address: null,
  phone: undefined,
  hobbies: [],
  settings: {},
  active: false,
  score: 0
}

const cleaned = shake(obj)
console.log(cleaned) // { name: 'Alice', age: 25, active: false, score: 0 }

處理嵌套對象

typescript
import { shake } from 'radash'

const obj = {
  user: {
    name: 'Alice',
    email: '',
    address: null,
    preferences: {}
  },
  settings: {
    theme: 'dark',
    notifications: null,
    language: ''
  },
  metadata: {
    created: new Date(),
    updated: null,
    tags: []
  }
}

const cleaned = shake(obj)
console.log(cleaned)
// {
//   user: { name: 'Alice' },
//   settings: { theme: 'dark' },
//   metadata: { created: 2023-12-31T12:00:00.000Z }
// }

處理數組值

typescript
import { shake } from 'radash'

const obj = {
  names: ['Alice', 'Bob'],
  scores: [],
  tags: [''],
  comments: null,
  items: [1, 2, 3],
  emptyArray: []
}

const cleaned = shake(obj)
console.log(cleaned) // { names: ['Alice', 'Bob'], items: [1, 2, 3] }

處理函數值

typescript
import { shake } from 'radash'

const obj = {
  handler: () => 'hello',
  validator: null,
  processor: undefined,
  callback: function() { return true },
  emptyFunction: () => {}
}

const cleaned = shake(obj)
console.log(cleaned)
// {
//   handler: [Function: handler],
//   callback: [Function: callback],
//   emptyFunction: [Function: emptyFunction]
// }

處理日期值

typescript
import { shake } from 'radash'

const obj = {
  createdAt: new Date('2023-01-01'),
  updatedAt: null,
  deletedAt: undefined,
  birthday: new Date('1998-05-15'),
  lastLogin: ''
}

const cleaned = shake(obj)
console.log(cleaned)
// {
//   createdAt: 2023-01-01T00:00:00.000Z,
//   birthday: 1998-05-15T00:00:00.000Z
// }

處理布爾值

typescript
import { shake } from 'radash'

const obj = {
  isActive: true,
  isVerified: false,
  isPremium: null,
  isBlocked: undefined,
  isPublic: ''
}

const cleaned = shake(obj)
console.log(cleaned) // { isActive: true, isVerified: false }

處理數字值

typescript
import { shake } from 'radash'

const obj = {
  score: 95,
  rating: 0,
  price: null,
  discount: undefined,
  quantity: '',
  total: -10
}

const cleaned = shake(obj)
console.log(cleaned) // { score: 95, rating: 0, total: -10 }

處理API響應數據

typescript
import { shake } from 'radash'

const apiResponse = {
  status: 200,
  data: {
    id: 1,
    name: 'Alice',
    email: '',
    address: null,
    phone: undefined
  },
  message: '',
  errors: null,
  meta: {
    timestamp: new Date(),
    version: '',
    debug: null
  }
}

const cleaned = shake(apiResponse)
console.log(cleaned)
// {
//   status: 200,
//   data: { id: 1, name: 'Alice' },
//   meta: { timestamp: 2023-12-31T12:00:00.000Z }
// }

處理表單數據

typescript
import { shake } from 'radash'

const formData = {
  personalInfo: {
    firstName: 'Alice',
    lastName: 'Smith',
    email: '',
    phone: null,
    age: 25
  },
  addressInfo: {
    street: '123 Main St',
    city: '',
    country: null,
    zipCode: '10001'
  },
  preferences: {
    newsletter: true,
    notifications: null,
    theme: 'dark',
    language: ''
  }
}

const cleaned = shake(formData)
console.log(cleaned)
// {
//   personalInfo: { firstName: 'Alice', lastName: 'Smith', age: 25 },
//   addressInfo: { street: '123 Main St', zipCode: '10001' },
//   preferences: { newsletter: true, theme: 'dark' }
// }

處理配置對象

typescript
import { shake } from 'radash'

const config = {
  server: {
    host: 'localhost',
    port: 3000,
    ssl: null,
    timeout: ''
  },
  database: {
    url: 'postgresql://localhost:5432/mydb',
    pool: {
      min: 1,
      max: 10,
      idle: null
    },
    logging: false
  },
  api: {
    version: 'v1',
    rateLimit: null,
    cors: {
      origin: '*',
      credentials: null
    }
  }
}

const cleaned = shake(config)
console.log(cleaned)
// {
//   server: { host: 'localhost', port: 3000 },
//   database: { url: 'postgresql://localhost:5432/mydb', pool: { min: 1, max: 10 }, logging: false },
//   api: { version: 'v1', cors: { origin: '*' } }
// }

處理錯誤對象

typescript
import { shake } from 'radash'

const errorObject = {
  name: 'ValidationError',
  message: 'Invalid input',
  code: '',
  details: {
    field: 'email',
    value: null,
    constraint: 'Must be a valid email',
    suggestions: []
  },
  stack: undefined,
  timestamp: new Date()
}

const cleaned = shake(errorObject)
console.log(cleaned)
// {
//   name: 'ValidationError',
//   message: 'Invalid input',
//   details: { field: 'email', constraint: 'Must be a valid email' },
//   timestamp: 2023-12-31T12:00:00.000Z
// }

處理日志數據

typescript
import { shake } from 'radash'

const logEntry = {
  level: 'ERROR',
  message: 'Database connection failed',
  timestamp: new Date(),
  userId: 123,
  requestId: '',
  context: {
    url: '/api/users',
    method: 'GET',
    params: null,
    headers: {}
  },
  error: {
    code: 'ECONNREFUSED',
    message: 'Connection refused',
    stack: undefined,
    details: null
  }
}

const cleaned = shake(logEntry)
console.log(cleaned)
// {
//   level: 'ERROR',
//   message: 'Database connection failed',
//   timestamp: 2023-12-31T12:00:00.000Z,
//   userId: 123,
//   context: { url: '/api/users', method: 'GET' },
//   error: { code: 'ECONNREFUSED', message: 'Connection refused' }
// }

處理數據庫查詢結果

typescript
import { shake } from 'radash'

const dbResult = {
  id: 1,
  name: 'Product A',
  description: '',
  price: 99.99,
  category: {
    id: 5,
    name: 'Electronics',
    description: null
  },
  tags: [],
  metadata: {
    created: new Date(),
    updated: null,
    version: '',
    flags: {}
  },
  variants: [
    { id: 101, color: 'Red', stock: 10 },
    { id: 102, color: 'Blue', stock: 0 }
  ]
}

const cleaned = shake(dbResult)
console.log(cleaned)
// {
//   id: 1,
//   name: 'Product A',
//   price: 99.99,
//   category: { id: 5, name: 'Electronics' },
//   metadata: { created: 2023-12-31T12:00:00.000Z },
//   variants: [{ id: 101, color: 'Red', stock: 10 }, { id: 102, color: 'Blue', stock: 0 }]
// }

處理空對象和邊界情況

typescript
import { shake } from 'radash'

// 空對象
console.log(shake({})) // {}

// 只包含空值的對象
console.log(shake({ a: null, b: undefined, c: '', d: [], e: {} })) // {}

// 只包含非空值的對象
console.log(shake({ a: 1, b: 'hello', c: true })) // { a: 1, b: 'hello', c: true }

// 包含零值的對象
console.log(shake({ a: 0, b: false, c: null, d: undefined })) // { a: 0, b: false }

處理復雜嵌套對象

typescript
import { shake } from 'radash'

const complexObj = {
  user: {
    profile: {
      name: 'Alice',
      email: '',
      avatar: null,
      bio: undefined
    },
    settings: {
      theme: 'dark',
      notifications: null,
      language: '',
      preferences: {}
    }
  },
  data: {
    items: [
      { id: 1, name: 'Item 1', description: '' },
      { id: 2, name: 'Item 2', description: null }
    ],
    metadata: {
      total: 2,
      page: 1,
      filters: null,
      sort: undefined
    }
  },
  system: {
    version: '1.0.0',
    environment: 'production',
    debug: false,
    logs: []
  }
}

const cleaned = shake(complexObj)
console.log(cleaned)
// {
//   user: {
//     profile: { name: 'Alice' },
//     settings: { theme: 'dark' }
//   },
//   data: {
//     items: [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }],
//     metadata: { total: 2, page: 1 }
//   },
//   system: { version: '1.0.0', environment: 'production', debug: false }
// }

處理枚舉映射

typescript
import { shake } from 'radash'

const statusMap = {
  active: 'ACTIVE',
  inactive: null,
  pending: '',
  suspended: undefined,
  deleted: 'DELETED'
}

const cleaned = shake(statusMap)
console.log(cleaned) // { active: 'ACTIVE', deleted: 'DELETED' }

處理顏色映射

typescript
import { shake } from 'radash'

const colorMap = {
  primary: '#FF0000',
  secondary: null,
  accent: '',
  warning: undefined,
  success: '#00FF00',
  info: ''
}

const cleaned = shake(colorMap)
console.log(cleaned) // { primary: '#FF0000', success: '#00FF00' }

注意事項

  1. 空值定義: 移除 nullundefined、空字符串 ''、空數組 []、空對象 {}
  2. 保留值: 保留 false0、負數等有效值
  3. 嵌套處理: 遞歸處理嵌套對象和數組
  4. 不可變性: 返回新對象,不修改原對象
  5. 類型安全: 支持TypeScript類型推斷

與其他方法的區別

  • Object.keys(): 獲取對象的所有鍵
  • shake(): 移除空值並返回新對象
  • omit(): 移除指定的鍵
  • pick(): 只保留指定的鍵

實際應用場景

  1. 數據清理: 清理API響應中的空值
  2. 表單處理: 移除表單中的空字段
  3. 配置處理: 清理配置對象中的空值
  4. 數據驗證: 准備數據用於驗證
  5. 存儲優化: 減少存儲空間佔用

Released under the MIT License.