Короткий ответ: typescript map может означать две разные вещи. Первая — метод массива Array.map, который преобразует каждый элемент. Вторая — структура данных Map<K, V>, где есть ключи и значения. Их важно не путать
Array.map
type Product = {
id: number;
title: string;
price: number;
};
const products: Product[] = [
{ id: 1, title: "Книга", price: 900 },
{ id: 2, title: "Курс", price: 4900 },
];
const titles = products.map((product) => product.title);
titles будет string[]. TypeScript сам выводит тип результата
Явный тип результата
type ProductView = {
label: string;
value: number;
};
const views: ProductView[] = products.map((product) => ({
label: product.title,
value: product.price,
}));
Если забыть value, TypeScript покажет ошибку, потому что результат должен соответствовать ProductView
Map<K, V>
Структура Map типизируется так:
const usersById = new Map<number, string>();
usersById.set(1, "Dinar");
usersById.set(2, "Alya");
Здесь ключ — number, значение — string
Получение:
const name = usersById.get(1);
Тип name будет string | undefined, потому что ключа может не быть
Проверка undefined
const name = usersById.get(3);
if (name !== undefined) {
console.log(name.toUpperCase());
}
Не используйте name! без необходимости. Оператор ! просто заставляет TypeScript поверить вам, но не проверяет данные
Async map
Частая ошибка:
const results = users.map(async (user) => loadProfile(user.id));
results будет Promise<Profile>[], а не Profile[]
Правильно:
const results = await Promise.all(
users.map((user) => loadProfile(user.id))
);
map с объектом-словарем
Если данные лежат в обычном объекте, у него нет метода .map:
const prices = {
book: 900,
course: 4900,
};
Чтобы преобразовать его, используйте Object.entries:
const items = Object.entries(prices).map(([key, price]) => ({
key,
price,
}));
Если нужен строгий набор ключей, задайте тип:
type PriceKey = "book" | "course";
const prices: Record<PriceKey, number> = {
book: 900,
course: 4900,
};
Так TypeScript проверит, что вы не забыли нужный ключ и не добавили случайный
Типизация callback
Обычно TypeScript сам понимает тип элемента:
products.map((product) => product.title);
Но если исходный массив не типизирован, callback тоже станет слабым. Поэтому начинайте с типа массива:
const products: Product[] = [];
Не нужно писать тип у каждого параметра map, если TypeScript уже выводит его из массива. Лучше типизировать источник данных, а не лечить каждый callback отдельно
Частые ошибки
Первая ошибка — путать Array.map и Map. Это разные вещи
Вторая ошибка — забывать, что Map.get() возвращает undefined, если ключа нет
Третья ошибка — не возвращать значение из callback:
const ids = products.map((product) => {
product.id;
});
Так получится void[]. Нужно:
const ids = products.map((product) => product.id);
Четвертая ошибка — ожидать, что async map сразу даст готовые значения. Нужен Promise.all
Пятая ошибка — пытаться вызвать .map у объекта. Метод .map есть у массива, а для объекта используйте Object.keys, Object.values или Object.entries
Самопроверка
Создайте массив товаров и получите массив строковых названий через map. Потом создайте Map<number, Product>, получите элемент через get и обработайте случай undefined
Что почитать дальше по TypeScript
Если нужен общий маршрут по теме, откройте рубрику TypeScript. Для соседних задач пригодятся эти разборы:
- TypeScript функция как аргумент: как типизировать callback
- Как типизировать массив объектов в TypeScript
- Как типизировать объект в TypeScript: практический разбор
- 10 вопросов по TypeScript и ответы на них



