index/functions/normalizeDataWithMapping.md
normalizeDataWithMapping<
T,R>(items,mapping):Partial<R>[]
Transform array of objects with field mapping and transformation functions
Maps field names from source objects to target field names, with optional transformation functions applied per field. Replaces manual map/reduce patterns.
Consolidates 4+ occurrences in:
- DTO → Domain conversions
- API response field renaming
- Array normalization workflows
Type Parameters
| Type Parameter | Description |
|---|---|
T extends Record<string, unknown> | Type of items in source array |
R extends Record<string, unknown> | Type of items in result array |
Parameters
| Parameter | Type | Description |
|---|---|---|
items | T[] | Array of source objects to transform |
mapping | Record<keyof R, (item) => unknown> | Record mapping target field names to transformation functions. Each function receives the source object and returns the value for that field. Undefined values are omitted from result. |
Returns
Partial<R>[]
Array of transformed objects with mapped field names
Examples
Basic field renaming
interface ApiUser {
user_name: string;
user_email: string;
created_at: string;
}
const apiUsers: ApiUser[] = [
{ user_name: 'alice', user_email: 'alice@example.com', created_at: '2025-01-01' }
];
const domainUsers = normalizeDataWithMapping(apiUsers, {
name: (item) => item.user_name,
email: (item) => item.user_email,
createdAt: (item) => item.created_at
});
// Returns: [{ name: 'alice', email: 'alice@example.com', createdAt: '2025-01-01' }]
With type transformations
interface RawPrice {
symbol: string;
price: string;
timestamp: string;
}
interface PriceData {
symbol: string;
price: number;
date: Date;
}
const rawPrices: RawPrice[] = [
{ symbol: 'BTC', price: '42500.50', timestamp: '2025-01-11T10:00:00Z' }
];
const prices = normalizeDataWithMapping<RawPrice, PriceData>(rawPrices, {
symbol: (item) => item.symbol,
price: (item) => parseFloat(item.price), // Transform string to number
date: (item) => new Date(item.timestamp) // Transform string to Date
});
// Returns: [{ symbol: 'BTC', price: 42500.5, date: Date }]
Conditional field inclusion
interface RawEvent {
id: string;
name: string;
description?: string;
verified?: boolean;
}
interface Event {
id: string;
title: string;
notes?: string;
trusted?: boolean;
}
const events = normalizeDataWithMapping<RawEvent, Event>(rawData, {
id: (item) => item.id,
title: (item) => item.name,
notes: (item) => item.description, // undefined if not present
trusted: (item) => item.verified // undefined if not present
});
// Undefined fields are omitted from result objects
Merging multiple source fields
interface TokenData {
first_name: string;
last_name: string;
amount: string;
}
interface TokenInfo {
fullName: string;
quantity: number;
}
const tokens = normalizeDataWithMapping<TokenData, TokenInfo>(data, {
fullName: (item) => `${item.first_name} ${item.last_name}`,
quantity: (item) => parseFloat(item.amount)
});