TypeScript является надстройкой над JavaScript, разработанной компанией Microsoft для решения проблем масштабирования JavaScript приложений. Основное преимущество TypeScript заключается в статической типизации.
Переменные в TypeScript объявляются с помощью ключевых слов let
, const
для изменяемых переменных let
и const
для констант. При объявлении переменной можно явно указать ее тип или позволить TypeScript автоматически вывести тип на основе присваиваемого значения.
// Явное указание типа
let userName: string = 'Алексей';
let userAge: number = 25;
let isLoggedIn: boolean = true;
// Автоматический вывод типа
let productName = 'Ноутбук MacBook'; // TypeScript понимает, что это string
let price = 99999; // TypeScript понимает, что это number
let isAvailable = false; // TypeScript понимает, что это boolean
// Константы
const PI = 3.14159; // number
const SITE_NAME = 'Мой интернет-магазин'; // string
const MAX_USERS = 1000; // number
Переменные, объявленные с let
, могут изменять свое значение в процессе выполнения программы, но не могут изменять тип данных. Константы, объявленные с const
, не могут изменять ни значение, ни тип после инициализации.
let counter = 0; // изначально number
counter = 10; // разрешено, тот же тип
counter = counter + 1; // разрешено
// counter = 'строка'; // ошибка: нельзя изменить тип с number на string
const companyName = 'TechCorp';
// companyName = 'NewTech'; // ошибка: нельзя изменять константу
В языке TypeScript можно использовать разные типы данных для хранения и обработки информации в переменных. К основным типам относятся строка (string), число (number), логический тип (boolean), значения null и undefined, а также особый тип any. Каждый тип данных имеет свои особенности и применение, и правильное использование типов делает код более безопасным и понятным.
Строки используются для хранения текстовой информации. Значения типа string можно брать в одинарные, двойные или обратные кавычки. Например:
let userName: string = 'Алексей';
let hello: string = "Привет!";
let longText: string = `Это многострочная
строка с переменными: ${userName}`;
Числовой тип представлен одним типом number, который подходит и для целых, и для дробных чисел. Например:
let age: number = 23;
let height: number = 1.75;
let money: number = 1000;
let temperature: number = -15.25;
Тип boolean хранит только значения true
или false
, что удобно для проверки условий:
let isAdmin: boolean = true;
let isOnline: boolean = false;
let canEdit: boolean = age > 18; // true, если age больше 18
В TypeScript также есть два специальных значения: null
и undefined
. Значение null
означает “отсутствие значения” и обычно используется, когда переменная должна хранить явно пустое значение:
let selectedUser: string | null = null;
selectedUser = "Виктор"; // теперь значение задано
selectedUser = null; // снова явно пусто
А значение undefined
используется, если переменная объявлена, но значение ей еще не присвоено, либо результат функции — “ничего не возвращено”:
let answer: string | undefined;
answer = "Yes";
answer = undefined; // либо не задано, либо явно неопределено
В TypeScript можно комбинировать типы через операторы union. Это бывает полезно, если переменная может принимать несколько разных типов:
let value: number | null = null; // или число, или null
value = 42;
value = null;
Также существует универсальный тип any
, который разрешает присваивать переменной любое значение, но его лучше избегать для сохранения типовой безопасности:
let unknownData: any = 3.1415;
unknownData = "строка";
unknownData = false;
Теперь рассмотрим массивы как отдельную структуру для хранения упорядоченных коллекций элементов.
Условные конструкции позволяют выполнять разные блоки кода в зависимости от выполнения определенных условий. Основной условный оператор if-else
проверяет логическое выражение и выполняет соответствующий блок кода.
let score: number = 85;
let grade: string;
if (score >= 90) {
grade = 'Отлично';
console.log('Поздравляем с отличной оценкой!');
} else if (score >= 70) {
grade = 'Хорошо';
console.log('Хороший результат!');
} else if (score >= 50) {
grade = 'Удовлетворительно';
console.log('Зачет получен.');
} else {
grade = 'Неудовлетворительно';
console.log('Нужно повторить материал.');
}
console.log(`Ваша оценка: ${grade}`);
Сложные условия могут комбинировать несколько логических выражений с помощью операторов &&
(логическое И), ||
(логическое ИЛИ) и !
(логическое НЕ).
let isGoodWeather: boolean = true;
let hasFreeTime: boolean = false;
// Проверяем, пойдем ли мы гулять
// Должны выполниться оба условия: хорошая погода И наличие свободного времени.
if (isGoodWeather && hasFreeTime) {
console.log('Отлично! Иду гулять.');
} else {
console.log('Не могу пойти гулять сейчас. Нужно проверить, что не так:');
// Уточняем причину
if (!isGoodWeather) { // Оператор ! (НЕ) инвертирует значение true на false и наоборот
console.log('- Погода плохая.');
}
if (!hasFreeTime) {
console.log('- Нет свободного времени.');
}
}
Тернарный оператор предоставляет краткую форму для простых условий, возвращая одно из двух значений в зависимости от условия.
let temperature: number = 22;
let weatherStatus: string = temperature > 20 ? 'Тепло' : 'Прохладно';
let clothingAdvice: string = temperature > 25 ? 'Легкая одежда' :
temperature > 15 ? 'Джинсы и футболка' :
'Теплая одежда';
console.log(`На улице ${weatherStatus}. Рекомендация: ${clothingAdvice}`);
Циклы позволяют повторять выполнение блока кода определенное количество раз или пока выполняется заданное условие.
Цикл for
является наиболее универсальным и часто используется когда известно точное количество итераций.
// Классический for цикл
for (let i = 0; i < 5; i++) {
console.log(`Итерация номер ${i + 1}`);
}
// Обратный отсчет
for (let countdown = 10; countdown >= 1; countdown--) {
console.log(`Осталось ${countdown} секунд`);
}
console.log('Время вышло!');
// Цикл с шагом
for (let num = 2; num <= 20; num += 2) {
console.log(`Четное число: ${num}`);
}
Цикл while
выполняется пока условие истинно. Важно убедиться, что условие в какой-то момент станет ложным, иначе получится бесконечный цикл.
let attempts = 0;
let maxAttempts = 3;
let isSuccess = false;
while (attempts < maxAttempts && !isSuccess) {
attempts++;
console.log(`Попытка ${attempts} из ${maxAttempts}`);
// Имитация случайного успеха
isSuccess = Math.random() > 0.6;
if (isSuccess) {
console.log('Операция выполнена успешно!');
} else if (attempts < maxAttempts) {
console.log('Неудача, повторяем...');
}
}
if (!isSuccess) {
console.log('Исчерпаны все попытки. Операция не удалась.');
}
Массив — это структура данных в TypeScript, предназначенная для хранения упорядоченного набора элементов. В отличие от отдельных переменных, массив позволяет сгруппировать множество однотипных значений под одним именем. Каждый элемент массива имеет свой индекс (позицию), начиная с нуля, что позволяет быстро получать доступ к любому элементу, изменять его значение или удалять.
Примеры объявления массивов:
const numbers: number[] = [10, 20, 30, 40];
const fruits: string[] = ["яблоко", "груша", "персик"];
const flags: boolean[] = [true, false, true];
const mixed: (string | number)[] = ["три", 3, "четыре", 4];
В массив можно добавлять элементы с помощью метода push
, удалять последний элемент — pop
:
numbers.push(50); // [10, 20, 30, 40, 50]
let last = fruits.pop(); // "персик", fruits теперь ["яблоко", "груша"]
Чтобы получить длину массива, используют свойство length
, а для доступа к элементам массив индексируется, начиная с нуля:
console.log(numbers[0]); // 10
console.log(fruits.length); // 2
Массивы в TypeScript обладают богатым набором встроенных методов, которые позволяют легко обрабатывать и трансформировать данные:
const upperFruits = fruits.map(fruit => fruit.toUpperCase());
console.log(upperFruits); // ["ЯБЛОКО", "ГРУША"]
const expensive = numbers.filter(num => num > 20);
console.log(expensive); // [30, 40, 50]
let firstBig = numbers.find(n => n > 25);
console.log(firstBig); // 30
console.log(fruits.includes("груша")); // true
console.log(numbers.some(num => num > 100)); // false
console.log(fruits.every(fruit => typeof fruit === "string")); // true
const sortedNumbers = numbers.sort((a, b) => a - b); // по возрастанию
console.log(sortedNumbers);
Функции позволяют группировать код в переиспользуемые блоки, принимать параметры и возвращать результаты.
Обычные функции объявляются с ключевым словом function
.
// Функция без параметров
function sayHello() {
console.log('Привет, мир!');
}
// Функция с параметрами и возвращаемым значением
function addNumbers(a: number, b: number) {
const result = a + b;
console.log(`${a} + ${b} = ${result}`);
return result;
}
// Вызов функций
sayHello();
let sum = addNumbers(15, 25);
Стрелочные функции представляют более краткий синтаксис для объявления функций.
// Обычная функция vs стрелочная функция
function regularMultiply(a: number, b: number): number {
return a * b;
}
const arrowMultiply = (a: number, b: number): number => {
return a * b;
};
// Краткая запись для простых функций (неявный return)
const quickMultiply = (a: number, b: number): number => a * b;
const square = (n: number): number => n * n;
const isEven = (num: number): boolean => num % 2 === 0;
console.log(regularMultiply(4, 5)); // 20
console.log(arrowMultiply(6, 7)); // 42
console.log(quickMultiply(8, 9)); // 72
console.log(square(5)); // 25
console.log(isEven(10)); // true
Объекты в TypeScript позволяют группировать связанные данные в единое целое. Они представляют собой коллекцию пар ключ-значение, где мы можем явно указывать типы для каждого свойства, что делает код более предсказуемым.
// Простой объект пользователя
const user = {
name: 'Алексей',
age: 25,
email: 'alex@example.com',
isActive: true
};
// Доступ к свойствам
console.log(user.name); // 'Алексей'
console.log(user['email']); // 'alex@example.com'
// Изменение свойств
user.age = 26;
user.isActive = false;
// Объект с вложенной структурой
const product = {
id: 1,
title: 'MacBook Pro',
price: 199999,
specifications: {
processor: 'M3 Pro',
memory: '16GB',
storage: '512GB SSD'
},
tags: ['Apple', 'Премиум', 'Профессиональный']
};
// Доступ к вложенным свойствам
console.log(product.specifications.processor); // 'M3 Pro'
console.log(product.tags[0]); // 'Apple'
Объекты могут содержать методы - функции, которые работают с данными объекта:
const calculator = {
result: 0,
add(value: number): number {
this.result += value;
return this.result;
},
subtract(value: number): number {
this.result -= value;
return this.result;
},
clear(): number {
this.result = 0;
return this.result;
}
};
// Использование методов
calculator.add(10); // result = 10
calculator.add(5); // result = 15
calculator.subtract(3); // result = 12
console.log(calculator.result); // 12
Типы позволяют определить структуру объектов заранее, что помогает обнаруживать ошибки на этапе разработки:
// Определение типа пользователя
type User = {
id: number;
name: string;
email: string;
age?: number; // опциональное свойство
isActive: boolean;
};
// Создание объекта с типом
let currentUser: User = {
id: 1,
name: 'Мария Петрова',
email: 'maria@example.com',
isActive: true
};
// Функция, работающая с типизированным объектом
function displayUser(user: User): string {
let info = `ID: ${user.id}, Имя: ${user.name}`;
if (user.age) {
info += `, Возраст: ${user.age}`;
}
return info;
}
// Тип для продукта
type Product = {
id: number;
name: string;
price: number;
category: string;
inStock: boolean;
rating: number;
};
// Union types для ограниченного набора значений
type Status = 'active' | 'inactive' | 'pending';
type Theme = 'light' | 'dark';
let userStatus: Status = 'active';
let appTheme: Theme = 'dark';
Работа с массивами объектов - одна из самых распространенных задач в веб-разработке:
// Массив продуктов
const products: Product[] = [
{
id: 1,
name: 'iPhone 15 Pro',
price: 129990,
category: 'Смартфоны',
inStock: true,
rating: 4.8
},
{
id: 2,
name: 'MacBook Air M2',
price: 109990,
category: 'Ноутбуки',
inStock: false,
rating: 4.9
},
{
id: 3,
name: 'iPad Pro',
price: 89990,
category: 'Планшеты',
inStock: true,
rating: 4.7
}
];
// Поиск товара по ID
function findProduct(products: Product[], id: number): Product | undefined {
return products.find(product => product.id === id);
}
// Фильтрация товаров в наличии
const availableProducts = products.filter(product => product.inStock);
console.log(`Товаров в наличии: ${availableProducts.length}`);
// Товары дороже 100000
const expensiveProducts = products.filter(product => product.price > 100000);
// Названия всех товаров
const productNames = products.map(product => product.name);
console.log('Все товары:', productNames);
// Сортировка по цене
const sortedByPrice = products.sort((a, b) => a.price - b.price);
// Общая стоимость всех товаров
const totalValue = products.reduce((sum, product) => sum + product.price, 0);
console.log(`Общая стоимость: ${totalValue.toLocaleString()} ₽`);
// Средний рейтинг
const averageRating = products.reduce((sum, p) => sum + p.rating, 0) / products.length;
console.log(`Средний рейтинг: ${averageRating.toFixed(1)}`);
// Комбинирование методов - топ-2 самых дорогих товара в наличии
const top2Expensive = products
.filter(product => product.inStock)
.sort((a, b) => b.price - a.price)
.slice(0, 2)
.map(product => ({ name: product.name, price: product.price }));
console.log('Топ-2 дорогих товара в наличии:', top2Expensive);
Задача: Напишите программу, которая проверяет возраст пользователя и выводит, может ли он получить водительские права.
let age: number = 17;
// Ваш код здесь:
// Если возраст >= 18, вывести "Вы можете получить водительские права"
// Если возраст >= 16 и < 18, вывести "Вы можете получить права на мотоцикл"
// Иначе вывести "Вы еще слишком молоды для получения прав"
Подсказка: Используйте конструкцию if-else if-else
как в примере с оценками из лекции.
Задача: Создайте программу, которая выводит таблицу умножения для числа 7 от 1 до 10.
let number: number = 7;
// Ваш код здесь:
// Используйте цикл for для вывода:
// 7 x 1 = 7
// 7 x 2 = 14
// ...
// 7 x 10 = 70
Задача: Создайте массив с температурами за неделю, добавьте температуру за 8-й день и найдите количество дней с температурой выше 20 градусов.
const temperatures: number[] = [18, 22, 25, 19, 23, 21, 20];
// Ваш код здесь:
// 1. Добавьте температуру 24 в конец массива
// 2. Используйте метод filter для получения температур > 20
// 3. Выведите количество таких дней
Задача: Создайте объект "книга" со свойствами: название, автор, год издания, количество страниц, прочитана ли книга.
// Ваш код здесь:
// Создайте объект book с полями:
// - title: string
// - author: string
// - year: number
// - pages: number
// - isRead: boolean
// Затем выведите информацию о книге в консоль
Подсказка: Используйте синтаксис объектов как в примере с user
.
Задача: Создайте массив из 3 студентов (каждый студент - объект с именем и оценкой), затем найдите студентов с оценкой выше 75 и выведите только их имена.
type Student = {
name: string;
grade: number;
};
// Ваш код здесь:
// 1. Создайте массив students с 3 студентами
// 2. Используйте filter для отбора студентов с grade > 75
// 3. Используйте map для получения только имен
// 4. Выведите результат в консоль
Подсказка: Комбинируйте методы filter()
и map()
как в примере с продуктами