После того как мы изучили введение в TypeScript и настроили среду разработки в первой части нашего курса, пришло время погрузиться глубже и начать изучение основных типов данных и переменных. В этой статье мы рассмотрим, как объявляются переменные в TypeScript и какие они бывают. Это ключевой шаг в освоении TypeScript, который поможет вам лучше понять, как создавать надежные и читаемые программы.

Объявление переменных в TypeScript

Объявление переменных — это основа любого языка программирования. В TypeScript, помимо объявления переменных, мы также имеем возможность явно указывать типы данных переменных. Это придает большую ясность коду и обеспечивает дополнительную защиту от ошибок.

В общем виде, объявление переменных в TypeScript имеет следующий синтаксис:

let/const/var variableName: type = value;
  • let, const или var — ключевые слова для объявления переменной.
  • variableName — имя переменной.
  • type — тип данных переменной (необязательно, если используется инференция типов).
  • value — начальное значение переменной.
let age: number = 25; // Объявление переменной "age" типа "number" со значением 25
const PI: number = 3.14; // Объявление константы "PI" типа "number" со значением 3.14
let name = "John"; // Использование инференции типов: "name" будет автоматически определен как тип "string"

Типы данных TypeScript

Когда мы говорим о типах данных в TypeScript, представьте себе набор инструментов в вашем ящике для обработки различных видов информации. Понимание этих типов данных поможет вам точно определить, какие данные вы хотите использовать в своей программе и как с ними работать. Давайте взглянем на самые распространенные типы данных:

Числа (Numbers)

Первый и, возможно, самый очевидный тип данных — числа. В TypeScript мы можем представить как целые, так и числа с плавающей запятой. Это может быть что угодно — от количества яблок в корзине до процента скидки на товар.

let age: number = 25;
let price: number = 9.99;

Строки (Strings)

Строковый тип данных представляет собой последовательность символов, будь то имя пользователя, текст сообщения или название продукта.

let name: string = "John";
let message: string = "Hello, TypeScript!";

Булевые значения (Boolean)

Булевый тип данных — это правда или ложь. Он используется для представления логических состояний, таких как активность пользователя или статус выполнения задачи.

let isActive: boolean = true;
let isCompleted: boolean = false;

Массивы (Arrays)

Массивы позволяют нам хранить упорядоченные коллекции элементов одного типа. Это может быть список покупок, набор чисел или даже строки.

let numbers: number[] = [1, 2, 3, 4, 5];
let fruits: string[] = ["apple", "banana", "orange"];

Объекты (Objects)

Объекты представляют собой набор свойств, каждое из которых имеет имя и значение. В TypeScript мы можем определить тип объекта, указав его свойства и их типы.

let person: { name: string; age: number } = { name: "John", age: 30 };

Кортежи (Tuples)

Кортежи позволяют определить фиксированное количество элементов с известными типами в определенном порядке.

let tuple: [string, number] = ["apple", 5];

Перечисления (Enums)

Перечисления — это специальный тип данных, который позволяет нам создавать именованные константы для набора значений.

enum Direction {
  Up,
  Down,
  Left,
  Right,
}
let direction: Direction = Direction.Up;

Void

Тип void используется для обозначения отсутствия какого-либо значения. Он обычно используется в контексте функций, которые не возвращают никакого значения.

function sayHello(): void {
  console.log("Hello!");
}

Неопределенный (Undefined)

Тип undefined представляет собой значение undefined, которое указывает на отсутствие значения.

let data: undefined = undefined;

Объединенные типы (Union Types)

Union types позволяют нам указывать несколько возможных типов для переменной.

let result: string | number;
result = "success";
result = 100;

Типы пересечения (Intersection Types)

Позволяют создавать новый тип, который содержит все свойства и методы, присущие каждому из объединенных типов. Это мощный механизм для комбинирования различных типов данных. Давайте рассмотрим примеры использования intersection types:

// Объявляем два различных типа данных
interface Animal {
  name: string;
  run(): void;
}

interface Bird {
  name: string;
  fly(): void;
}

// Используем intersection type для создания нового типа
type BirdAnimal = Animal & Bird;

// Теперь переменная типа BirdAnimal содержит свойства и методы как у Animal, так и у Bird
let bird: BirdAnimal = {
  name: "Sparrow",
  run() {
    console.log("Running...");
  },
  fly() {
    console.log("Flying...");
  },
};

В приведенном выше примере, BirdAnimal — это intersection type, который содержит свойства и методы обоих интерфейсов Animal и Bird. Таким образом, переменная bird должна иметь как метод run, так и метод fly.

Отличие между Union types и Intersection types заключается в том, как они комбинируют типы данных. Union types объединяют два или более типа данных так, чтобы переменная могла содержать значение любого из них. Intersection types создают новый тип, который содержит свойства и методы из всех исходных типов данных. Таким образом, Union types позволяют переменной принимать значения различных типов, в то время как Intersection types создают новый тип, содержащий совокупность свойств и методов всех исходных типов.

Любой тип (Any)

Тип данных any в TypeScript представляет собой специальный тип, который позволяет переменным принимать значения любого типа. Использование any отключает проверку типов во время компиляции, что делает его удобным инструментом в ситуациях, когда тип данных переменной может быть неизвестен во время написания кода или когда необходимо обрабатывать данные с разными типами.

let variable: any;

variable = 10; // присвоение числового значения
console.log(variable); // Вывод: 10

variable = "Hello"; // присвоение строкового значения
console.log(variable); // Вывод: Hello

variable = true; // присвоение булевого значения
console.log(variable); // Вывод: true

Использование any может уменьшить статическую проверку типов и увеличить вероятность возникновения ошибок во время выполнения программы.

Никогда (Never)

Тип never в TypeScript используется для обозначения ситуаций, когда функция никогда не должна завершиться нормально и не должна возвращать какое-либо значение, либо когда переменная никогда не должна принимать какие-либо значения. В основном, never указывает на недостижимый код или ошибки времени выполнения.

Вот несколько распространенных случаев, когда используется never:

Функции, которые никогда не завершаются:

function throwError(message: string): never {
    throw new Error(message);
}

В этом примере функция throwError генерирует ошибку и никогда не завершается нормально. Поэтому ее возвращаемый тип указан как never.

Функции, которые бесконечно выполняются:

function infiniteLoop(): never {
    while (true) {
        // Делаем что-то бесконечно
    }
}

Эта функция также не завершается нормально и создает бесконечный цикл.

Переменные, которые не имеют никакого значения:

let error: never;
error = (() => { throw new Error("Something went wrong"); })();

В этом примере переменная error никогда не получает какое-либо значение, кроме того, которое возникает при генерации ошибки.