keys
獲取對象的所有鍵名,返回一個數組。
基礎用法
typescript
import { keys } from 'radash'
const user = {
id: 1,
name: 'Alice',
email: 'alice@example.com'
}
console.log(keys(user)) // ['id', 'name', 'email']
語法
typescript
function keys<T extends Record<string, any>>(obj: T): (keyof T)[]
參數
obj
(T): 要獲取鍵名的對象
返回值
返回一個包含對象所有鍵名的數組。
示例
基本對象鍵名獲取
typescript
import { keys } from 'radash'
const user = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
age: 25
}
const keyNames = keys(user)
console.log(keyNames) // ['id', 'name', 'email', 'age']
空對象處理
typescript
import { keys } from 'radash'
console.log(keys({})) // []
console.log(keys({ a: 1 })) // ['a']
嵌套對象鍵名
typescript
import { keys } from 'radash'
const user = {
id: 1,
profile: {
name: 'Alice',
email: 'alice@example.com'
},
settings: {
theme: 'dark',
notifications: true
}
}
const keyNames = keys(user)
console.log(keyNames) // ['id', 'profile', 'settings']
// 獲取嵌套對象的鍵名
const profileKeys = keys(user.profile)
console.log(profileKeys) // ['name', 'email']
const settingsKeys = keys(user.settings)
console.log(settingsKeys) // ['theme', 'notifications']
處理不同類型的值
typescript
import { keys } from 'radash'
const mixedObject = {
string: 'hello',
number: 123,
boolean: true,
null: null,
undefined: undefined,
array: [1, 2, 3],
object: { a: 1 },
function: () => {}
}
const keyNames = keys(mixedObject)
console.log(keyNames) // ['string', 'number', 'boolean', 'null', 'undefined', 'array', 'object', 'function']
表單字段驗證
typescript
import { keys } from 'radash'
function validateRequiredFields(data: Record<string, any>, requiredFields: string[]) {
const dataKeys = keys(data)
const missingFields = requiredFields.filter(field => !dataKeys.includes(field))
return {
isValid: missingFields.length === 0,
missingFields
}
}
const formData = {
name: 'Alice',
email: 'alice@example.com',
age: 25
}
const requiredFields = ['name', 'email', 'phone']
const validation = validateRequiredFields(formData, requiredFields)
console.log(validation) // { isValid: false, missingFields: ['phone'] }
對象比較
typescript
import { keys } from 'radash'
function compareObjects(obj1: Record<string, any>, obj2: Record<string, any>) {
const keys1 = keys(obj1)
const keys2 = keys(obj2)
const commonKeys = keys1.filter(key => keys2.includes(key))
const uniqueToObj1 = keys1.filter(key => !keys2.includes(key))
const uniqueToObj2 = keys2.filter(key => !keys1.includes(key))
return {
commonKeys,
uniqueToObj1,
uniqueToObj2,
hasSameKeys: keys1.length === keys2.length && uniqueToObj1.length === 0
}
}
const obj1 = { a: 1, b: 2, c: 3 }
const obj2 = { b: 2, c: 3, d: 4 }
const comparison = compareObjects(obj1, obj2)
console.log(comparison)
// {
// commonKeys: ['b', 'c'],
// uniqueToObj1: ['a'],
// uniqueToObj2: ['d'],
// hasSameKeys: false
// }
動態屬性訪問
typescript
import { keys } from 'radash'
function getObjectValues(obj: Record<string, any>, filter?: (key: string) => boolean) {
const objectKeys = keys(obj)
const filteredKeys = filter ? objectKeys.filter(filter) : objectKeys
return filteredKeys.map(key => obj[key])
}
const user = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
age: 25,
isActive: true
}
// 獲取所有值
const allValues = getObjectValues(user)
console.log(allValues) // [1, 'Alice', 'alice@example.com', 25, true]
// 獲取字符串類型的值
const stringValues = getObjectValues(user, key => typeof user[key] === 'string')
console.log(stringValues) // ['Alice', 'alice@example.com']
// 獲取數字類型的值
const numberValues = getObjectValues(user, key => typeof user[key] === 'number')
console.log(numberValues) // [1, 25]
配置對象處理
typescript
import { keys } from 'radash'
function validateConfig(config: Record<string, any>) {
const configKeys = keys(config)
const errors: string[] = []
const requiredKeys = ['apiUrl', 'databaseUrl', 'port']
const optionalKeys = ['timeout', 'retries', 'cache']
// 檢查必需字段
for (const requiredKey of requiredKeys) {
if (!configKeys.includes(requiredKey)) {
errors.push(`Missing required field: ${requiredKey}`)
}
}
// 檢查未知字段
const allValidKeys = [...requiredKeys, ...optionalKeys]
const unknownKeys = configKeys.filter(key => !allValidKeys.includes(key))
if (unknownKeys.length > 0) {
errors.push(`Unknown fields: ${unknownKeys.join(', ')}`)
}
return {
isValid: errors.length === 0,
errors
}
}
const config = {
apiUrl: 'https://api.example.com',
databaseUrl: 'postgresql://localhost:5432/mydb',
port: 3000,
timeout: 5000,
unknownField: 'value'
}
const validation = validateConfig(config)
console.log(validation)
// {
// isValid: false,
// errors: ['Unknown fields: unknownField']
// }
對象轉換
typescript
import { keys } from 'radash'
function transformObject(obj: Record<string, any>, transformer: (key: string, value: any) => any) {
const objectKeys = keys(obj)
const transformed: Record<string, any> = {}
for (const key of objectKeys) {
transformed[key] = transformer(key, obj[key])
}
return transformed
}
const user = {
name: 'alice',
email: 'alice@example.com',
age: 25
}
// 轉換鍵名為大寫
const upperCaseKeys = transformObject(user, (key, value) => value)
console.log(upperCaseKeys) // { name: 'alice', email: 'alice@example.com', age: 25 }
// 轉換值為大寫(如果是字符串)
const upperCaseValues = transformObject(user, (key, value) =>
typeof value === 'string' ? value.toUpperCase() : value
)
console.log(upperCaseValues) // { name: 'ALICE', email: 'ALICE@EXAMPLE.COM', age: 25 }
對象深度遍歷
typescript
import { keys } from 'radash'
function getNestedKeys(obj: Record<string, any>, prefix = ''): string[] {
const objectKeys = keys(obj)
const nestedKeys: string[] = []
for (const key of objectKeys) {
const fullKey = prefix ? `${prefix}.${key}` : key
nestedKeys.push(fullKey)
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
nestedKeys.push(...getNestedKeys(obj[key], fullKey))
}
}
return nestedKeys
}
const nestedObject = {
user: {
profile: {
name: 'Alice',
email: 'alice@example.com'
},
settings: {
theme: 'dark'
}
},
config: {
api: {
url: 'https://api.example.com'
}
}
}
const nestedKeys = getNestedKeys(nestedObject)
console.log(nestedKeys)
// [
// 'user',
// 'user.profile',
// 'user.profile.name',
// 'user.profile.email',
// 'user.settings',
// 'user.settings.theme',
// 'config',
// 'config.api',
// 'config.api.url'
// ]
對象統計
typescript
import { keys } from 'radash'
function analyzeObject(obj: Record<string, any>) {
const objectKeys = keys(obj)
const analysis = {
totalKeys: objectKeys.length,
keyTypes: objectKeys.reduce((acc, key) => {
const type = typeof obj[key]
acc[type] = (acc[type] || 0) + 1
return acc
}, {} as Record<string, number>),
keyNames: objectKeys,
hasNestedObjects: objectKeys.some(key =>
typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])
)
}
return analysis
}
const complexObject = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
isActive: true,
profile: {
age: 25,
city: 'Beijing'
},
tags: ['developer', 'frontend'],
lastLogin: null
}
const analysis = analyzeObject(complexObject)
console.log(analysis)
// {
// totalKeys: 7,
// keyTypes: { number: 1, string: 2, boolean: 1, object: 1, array: 1, object: 1 },
// keyNames: ['id', 'name', 'email', 'isActive', 'profile', 'tags', 'lastLogin'],
// hasNestedObjects: true
// }
對象序列化
typescript
import { keys } from 'radash'
function serializeObject(obj: Record<string, any>): string {
const objectKeys = keys(obj)
const pairs = objectKeys.map(key => `${key}=${encodeURIComponent(String(obj[key]))}`)
return pairs.join('&')
}
const user = {
name: 'Alice Smith',
email: 'alice@example.com',
age: 25,
isActive: true
}
const serialized = serializeObject(user)
console.log(serialized) // 'name=Alice%20Smith&email=alice%40example.com&age=25&isActive=true'
對象過濾
typescript
import { keys } from 'radash'
function filterObject(obj: Record<string, any>, predicate: (key: string, value: any) => boolean) {
const objectKeys = keys(obj)
const filtered: Record<string, any> = {}
for (const key of objectKeys) {
if (predicate(key, obj[key])) {
filtered[key] = obj[key]
}
}
return filtered
}
const user = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
age: 25,
isActive: true,
lastLogin: null
}
// 過濾掉空值
const nonNullValues = filterObject(user, (key, value) => value !== null && value !== undefined)
console.log(nonNullValues) // { id: 1, name: 'Alice', email: 'alice@example.com', age: 25, isActive: true }
// 過濾字符串類型的值
const stringValues = filterObject(user, (key, value) => typeof value === 'string')
console.log(stringValues) // { name: 'Alice', email: 'alice@example.com' }
注意事項
- 鍵名順序: 返回的鍵名順序與對象定義順序一致
- 繼承屬性: 只返回對象自身的可枚舉屬性
- Symbol鍵: 不包含Symbol類型的鍵名
- 性能: 對於大型對象,性能良好
- 類型安全: 提供完整的TypeScript類型支持
與其他方法的區別
Object.keys()
: 原生方法,功能相同keys()
: radash提供的鍵名獲取方法Object.getOwnPropertyNames()
: 包含不可枚舉屬性Reflect.ownKeys()
: 包含Symbol鍵
實際應用場景
- 表單驗證: 檢查必需字段是否存在
- 對象比較: 比較兩個對象的鍵名差異
- 動態屬性訪問: 根據鍵名動態訪問對象屬性
- 對象轉換: 批量處理對象屬性
- 配置管理: 驗證配置對象的完整性