Типы данных и аннотации типов

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

Примитивные типы данных

TypeScript в Angular поддерживает все стандартные примитивные типы данных JavaScript, а также несколько дополнительных типов для работы с аннотациями типов.

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

    let age: number = 25;
    let temperature: number = 36.6;
  2. string Тип для строковых значений. Все строки в TypeScript — это неизменяемые объекты, состоящие из символов.

    let name: string = "Angular";
    let greeting: string = 'Hello, World!';
  3. boolean Тип, представляющий логические значения: true или false.

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

Сложные типы данных

TypeScript поддерживает более сложные типы данных, такие как массивы, кортежи и объекты.

  1. Array Массивы в TypeScript объявляются с использованием обобщений (generics). Можно указать тип элементов массива.

    let numbers: number[] = [1, 2, 3, 4];
    let strings: Array = ["apple", "banana", "cherry"];
  2. Tuple Кортежи — это массивы с фиксированным количеством элементов, где каждый элемент может быть разных типов.

    let person: [string, number] = ["John", 30];
  3. Object Объект может быть объявлен с типами ключей и значений. Можно использовать интерфейсы для более точной типизации объектов.

    let user: { name: string, age: number } = { name: "Alice", age: 28 };

Типы any и unknown

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

    let value: any = 42;
    value = "A string now";
    value = true;
  2. unknown В отличие от any, тип unknown является более безопасным. Значение типа unknown нельзя использовать до тех пор, пока не будет выполнена проверка типа.

    let result: unknown = 42;
    if (typeof result === "number") {
      let sum = result + 10; // Это безопасно
    }

Специальные типы

  1. void Тип void обычно используется для функций, которые не возвращают значения. Это эквивалент undefined в JavaScript.

    function logMessage(message: string): void {
      console.log(message);
    }
  2. null и undefined В TypeScript типы null и undefined обозначают отсутствие значения, но они отличаются от остальных типов. Включение строгой проверки типов (strictNullChecks) позволяет отделить эти значения от других типов.

    let notAssigned: null = null;
    let uninitialized: undefined = undefined;
  3. never Тип never используется для значений, которые никогда не могут быть возвращены. Это может быть полезно в функциях, которые всегда выбрасывают исключения или имеют бесконечные циклы.

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

Аннотации типов

Аннотация типов в TypeScript позволяет явно указывать тип данных переменных, параметров и возвращаемых значений функций. Аннотации помогают компилятору TypeScript точно проверить типы во время разработки, предотвращая многие потенциальные ошибки.

Переменные

Тип переменной можно указать сразу при её объявлении, используя двоеточие : и указание типа.

let isAvailable: boolean = true;
let score: number = 100;
let userName: string = "Jane";

Функции

Типы для параметров функции и её возвращаемого значения также указываются с помощью аннотаций.

function add(a: number, b: number): number {
  return a + b;
}

function greet(name: string): void {
  console.log(`Hello, ${name}`);
}

Массивы и объекты

Массивы и объекты можно аннотировать с помощью синтаксиса, предоставляющего информацию о типах их элементов или свойств.

let numbers: number[] = [1, 2, 3];
let user: { name: string, age: number } = { name: "Alice", age: 30 };

Интерфейсы

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

interface Person {
  name: string;
  age: number;
  greet(): void;
}

let person: Person = {
  name: "John",
  age: 25,
  greet() {
    console.log(`Hello, ${this.name}`);
  }
};

Генерики

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

function identity(arg: T): T {
  return arg;
}

let output = identity("Hello, World!"); // string
let numberOutput = identity(42); // number

Типизация в Angular

В контексте Angular типизация становится важным инструментом для создания надежных и масштабируемых приложений. Использование интерфейсов и строгих типов помогает избежать многих ошибок при взаимодействии между компонентами, сервисами и другими частями приложения.

Сервисы и зависимость

В Angular, когда используется сервис, его типизация через аннотацию помогает точно определять интерфейсы, через которые происходит взаимодействие.

@Injectable({
  providedIn: 'root'
})
export class UserService {
  private users: User[] = [];

  constructor() {}

  getUsers(): User[] {
    return this.users;
  }
}

Компоненты и шаблоны

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

@Component({
  selector: 'app-user',
  template: `
{{ user.name }}
` }) export class UserComponent { @Input() user: User; constructor() {} }

Аннотации типов и использование TypeScript в Angular позволяет значительно улучшить поддержку, читаемость и производительность кода, а также снизить количество ошибок на этапе разработки.