feat(core-extensions)!: Rename Object.map to mapValues

This commit is contained in:
T. R. Bernstein
2025-04-21 20:49:57 +02:00
parent 2e7c604218
commit 9c14996ed8
6 changed files with 66 additions and 21 deletions

View File

@@ -0,0 +1,3 @@
import type { Simplify } from 'type-fest'
export type MappedObjectValues<T extends object, U> = Simplify<{ [K in keyof T]: U }>

View File

@@ -0,0 +1 @@
export type ObjectValueMapper<T extends object, U> = (value: T[keyof T], key: keyof T, obj: T) => U

View File

@@ -0,0 +1,17 @@
import type { MappedObjectValues } from '@/internal/mapped-object-values.type.js'
import type { ObjectValueMapper } from '@/internal/object-value-mapper.type.js'
export function mapValues<T extends object, U>(
obj: T,
fn: ObjectValueMapper<T, U>
): MappedObjectValues<T, U> {
const result = {} as { [K in keyof T]: U }
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
result[key] = fn(obj[key], key, obj)
}
}
return result
}

View File

@@ -0,0 +1,23 @@
import { describe, it, expect } from 'vitest'
import './map-values.js'
import { mapValues } from './map-values.f.js'
describe('Object.mapValues', () => {
it('doubles all numeric values', async () => {
const obj = { a: 1, b: 5 }
const doubled = mapValues(obj, (val) => val * 2)
const doubledProto = obj.mapValues((val) => val * 2)
expect(doubled).toEqual(doubledProto)
expect(doubled).toEqual({ a: 2, b: 10 })
})
it('creates indexed string', async () => {
const obj = { a: 1, b: 5, c: 'some' }
const indexedString = mapValues(obj, (val, key) => `${key}${val}`)
const indexedStringProto = obj.mapValues((val, key) => `${key}${val}`)
expect(indexedString).toEqual(indexedStringProto)
expect(indexedString).toEqual({ a: 'a1', b: 'b5', c: 'csome' })
})
})

View File

@@ -0,0 +1,22 @@
import type { MappedObjectValues } from '@/internal/mapped-object-values.type.js'
import type { ObjectValueMapper } from '@/internal/object-value-mapper.type.js'
import { mapValues } from './map-values.f.js'
const objectMapValues = function <T extends object, U>(
this: T,
callback: ObjectValueMapper<T, U>
): MappedObjectValues<T, U> {
return mapValues(this, callback)
}
declare global {
interface Object {
mapValues: typeof objectMapValues
}
}
Object.defineProperty(Object.prototype, 'mapValues', {
value: objectMapValues
})
export {}

View File

@@ -1,21 +0,0 @@
declare global {
interface Object {
map<T, U>(
this: Record<string, T>,
callback: (value: T, key: string, obj: Record<string, T>) => U
): Record<string, U>
}
}
Object.prototype.map = function <T, U>(
this: Record<string, T>,
callback: (value: T, key: string, obj: Record<string, T>) => U
): Record<string, U> {
const result: Record<string, U> = {}
for (const [key, value] of Object.entries(this)) {
result[key] = callback(value, key, this)
}
return result
}
export {}