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键
实际应用场景
- 表单验证: 检查必需字段是否存在
- 对象比较: 比较两个对象的键名差异
- 动态属性访问: 根据键名动态访问对象属性
- 对象转换: 批量处理对象属性
- 配置管理: 验证配置对象的完整性