Skip to main content

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 ParameterDescription
T extends Record<string, unknown>Type of items in source array
R extends Record<string, unknown>Type of items in result array

Parameters​

ParameterTypeDescription
itemsT[]Array of source objects to transform
mappingRecord<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)
});