Базовые типы
Базовые типы
Технический фундамент вывода типов
TypeScript не только читает аннотации, но и активно выводит типы автоматически:
constобычно фиксирует более узкий literal-тип;letчаще приводит к расширенному типу (widening);- инициализатор влияет на будущий контракт переменной;
- явная аннотация особенно полезна на границах модулей и в публичных API.
Практический вывод: чем точнее исходная аннотация или инициализация, тем меньше "размытия" типов дальше по коду.
Мини-пример const/let, widening и as const:
const role1 = 'admin'; // тип: "admin" (literal)
let role2 = 'admin'; // тип: string (widening)
const user1 = { role: 'admin' }; // тип: { role: string } (поле можно менять)
const user2 = { role: 'admin' } as const; // тип: { readonly role: "admin" }
const point1 = [10, 20]; // тип: number[]
const point2 = [10, 20] as const; // тип: readonly [10, 20]
Смотри, что важно: const фиксирует ссылку на объект/массив, но не делает вложенные поля неизменяемыми. Если важно сохранить literal-типы и получить readonly-поведение для литерала, используется as const.
Почему базовые типы это фундамент
Если в TypeScript неправильно задана база типов, все остальные преимущества быстро теряются. Базовые типы задают контракты для переменных, аргументов и результатов функций. Это первый фильтр против ошибок "не тот формат данных".
Ключевой момент: чем точнее базовый тип, тем раньше ты ловишь проблему.
Проверь себя: почему any убирает большую часть пользы TypeScript?
Основные примитивные типы
Чаще всего ты используешь:
string;number;boolean;null;undefined;bigint;symbol.
let userName: string = 'Anna';
let age: number = 25;
let isAdmin: boolean = false;
Смотри, что важно: TypeScript часто умеет вывести тип сам (type inference), но явные аннотации полезны на границах API и в публичных функциях.
Массивы и кортежи
Массивы можно описывать двумя способами:
const scores: number[] = [10, 20, 30];
const tags: Array<string> = ['js', 'ts'];
Кортеж (tuple) фиксирует длину и типы по позициям.
const point: [number, number] = [10, 20];
Здесь часто путаются: number[] это "любой длины список чисел", а [number, number] это строго два числа.
Проверь себя: подойдет ли number[] для координаты, где обязательно ровно две оси?
any, unknown, void, never
any- отключает проверку типов (использовать осторожно).unknown- "неизвестный тип", требует проверки перед использованием.void- отсутствие полезного возвращаемого значения.never- функция не возвращает управление (например, всегда кидает ошибку).
function logMessage(msg: string): void {
console.log(msg);
}
function fail(message: string): never {
throw new Error(message);
}
unknown безопаснее any, потому что заставляет сузить тип перед использованием.
function printValue(value: unknown) {
if (typeof value === 'string') {
console.log(value.toUpperCase());
}
}
Union-типы
Union позволяет переменной принимать несколько типов.
let id: string | number;
id = 10;
id = 'user-10';
Это полезно, когда вход реально бывает в нескольких форматах.
Мини-сценарий: API возвращает id как number в одной версии и как string в другой.
Реальные микро-сценарии
- Форма профиля.
email: string, age: number | null, isSubscribed: boolean.
- Параметр маршрута.
productId: string | number до нормализации.
- Логгер.
message: unknown на входе и безопасное сужение перед обработкой.
Частые ошибки новичков
- Использовать
anyвместо продуманного union/unknown. - Путать
nullиundefinedв контрактах. - Игнорировать кортежи там, где важен фиксированный формат.
- Писать слишком широкие типы, которые не защищают от ошибок.
Анти-провал: если не уверен, начни с unknown и постепенно уточни типы через проверки.
Что будет, если изменить входные данные
Если функция ожидает number, а ей передают '42', TypeScript сразу сообщит о несоответствии. Если тип был string | number, придется явно решить, как обрабатывать оба случая. Это делает бизнес-логику прозрачной, а не скрытой в неявных преобразованиях.
Проверь себя: когда union полезен, а когда он слишком размывает контракт?
Краткий итог
- Базовые типы в TypeScript формируют основу безопасного кода.
string,number,booleanи массивы покрывают большинство повседневных сценариев.unknownобычно лучшеanyдля безопасного старта с неизвестными данными.- Union-типы полезны для реальных многовариантных входов.
- Точность типа на раннем этапе уменьшает количество багов на поздних стадиях.