# Інші типи даних (any, unknown, tuple, enum, union type, literal type)

## Any

<mark style="background-color:red;">any</mark> - це спеціальний тип. Його можна використовувати, щоб вказати, що змінна може мати будь-який тип. Це менш безпечний тип, і його слід використовувати з обережністю.

```typescript
let dynamicValue: any = "Hello";
dynamicValue = 42; 
```

**Головний недолік** any в тому, що його можна присвоїти змінній з іншим визначеним типом і це не буде вважатися помилкою, бо any також включає цей тип даних.

```typescript
let dynamicValue: any = "Hello";

let someNumber: number = dynamicValue;
```

Як бачимо на прикладі в змінній dynamicValue із типом any зберігається рядок і цей рядок ми присвоюємо змінній someNumber, яка має тип число. Але TypeScript нам не покаже помилки. &#x20;

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FN7XiRBDzZJwjJorYTPeW%2Fany_no_error.png?alt=media&#x26;token=e2813e4e-ce86-407c-9e93-bca74079acef" alt="" width="298"><figcaption></figcaption></figure>

Так само при використанні типу any не відбувається перевірка чи існує якийсь параметр в обʼєкті. Тобто запис наведений нижче зовсім не вкаже на помилку.

```typescript
let dynamicValue: any;

// dynamicValue = { name: "Alex" };

let a = dynamicValue.name;
```

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FDGg9IFfmbiMx5q6DUS6N%2Fobject-any-no-error.png?alt=media&#x26;token=88b0cdc5-436e-42bd-884f-3a4b66263a22" alt="" width="272"><figcaption></figcaption></figure>

## Unknown

Цей тип даних допомагає уникнути недоліку попереднього типу даних. Так, припустимо є змінна з типом даних unknown в якій зберігається рядок і ми її спробуємо присвоїти іншій змінній визначеній за типом даних число, то буде помилка.&#x20;

```typescript
let dynamicValue: unknown = "Hello";

let someNumber: number = dynamicValue;
```

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FoxZrwYMr7wSKxhoJGNep%2Funknown-1.png?alt=media&#x26;token=32dac412-709c-4e3f-9b97-f1349df7110e" alt="" width="302"><figcaption></figcaption></figure>

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FFkEKB3MLA5dskLfdyHba%2Funknown-2.png?alt=media&#x26;token=ef8164fe-fa9b-4f21-8368-12cf558b86f0" alt="" width="375"><figcaption></figcaption></figure>

Щоб уникнути помилки, перед присвоєнням значення потрібно перевірити тип змінної. Якщо він збігається, то присвоєння  відбудеться, якщо типи даних відрізняються, то операція проігнорується.

```typescript
let dynamicValue: unknown = "Hello";

let someNumber: number; 
  
if (typeof dynamicValue === 'number') {
   someNumber = dynamicValue;
}
```

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FuscLIIpM4gHc52u1gbjm%2Funknown-3.png?alt=media&#x26;token=ec9dd15e-dd5a-4238-b5ca-354756eea920" alt="" width="311"><figcaption></figcaption></figure>

Такі вирази називають <mark style="background-color:red;">Type Guard</mark>, тобто такі що перевіряють тип змінної.

## Tuple

У TypeScript "кортеж" (Tuple) - це тип даних, який дозволяє визначити масив з фіксованою кількістю елементів, де кожен елемент може мати свій власний тип даних. Особливість кортежів полягає в тому, що вони дозволяють визначити типи для кожного елемента в масиві в певному порядку.

```typescript
let person: [string, number] = ["Alice", 25];
```

Якщо якомусь елементу масиву спробувати записати вміст невідповідного типу даних, то буде помилка.

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FNhQaSwdoAIgQNaAY4wPw%2FTuple-error.png?alt=media&#x26;token=f0947327-5af1-498b-8cc0-b5ae18f9700c" alt="" width="350"><figcaption></figcaption></figure>

Кортежі особливо корисні в ситуаціях, коли  потрібно мати точний контроль над типами даних і кількістю елементів у структурі даних.

**Недолік**: Компілятор не відстежує реальний вміст масиву тому методи масивів, наприклад метод push() він пропустить і не покаже помилки.

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FXaycvIFqS0qgo0xMAJdf%2FTuple-noerror-push.png?alt=media&#x26;token=7e59b5e5-7c78-4830-b264-72ff0dce7e1a" alt="" width="352"><figcaption></figcaption></figure>

## Enum <a href="#enum" id="enum"></a>

enum - це перелічуваний тип даних, який дозволяє  створювати набір іменованих констант, які представляють цілі числові значення.&#x20;

Перелічувані типи допомагають зробити код більш зрозумілим та читабельним, оскільки вони надають змінним зрозумілі та описові імена замість чисел.

Змінні в enum заведено називати з великої літери.

```typescript
enum Status { Pending, InProgress, Completed}
```

Якщо ми виведемо в консолі значення кожного елемента в enum Status, то побачимо його числовий відповідник. По замовчуванню, enum присвоює числові значення кожній з констант, починаючи з нуля

```typescript
console.log("Pending: ", Status.Pending); // 0
console.log("InProgress: ", Status.InProgress); // 1
console.log("Completed: ", Status.Completed); // 2
```

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FKU8xtJ9MMO15DVBv6aHH%2Fenum-console1.png?alt=media&#x26;token=a566fc16-5641-47c7-8657-2f2940db28d0" alt="" width="375"><figcaption></figcaption></figure>

Однак можна призначити власні значення, якщо це потрібно:

```typescript
enum Status {
  Pending = 1,
  InProgress = 2,
  Completed = 3,
}
```

По суті це навіть не зовсім тип даних, а більше йде як паттерн.&#x20;

Зручно використовувати для гарного коду, оскільки візуально видно, що певний статус змінної, чи, наприклад користувача ми перевіряємо не просто з якимось числом, а з візуально зрозумілим статусом (значенням).

Наприклад у нас є процес із трьома можливими статусами Pending, InProgress, Completed. І в якійсь змінній зберігається актуальний статус процесу (наприклад завантаження сторінки). В такому разі, наприклад при збігу цього статусу з одним із значень enum ми можемо ввімкнути лоадер або вимкнути. тощо. Зобразімо це в коді нижче.

```typescript
enum Status {
  Pending,
  InProgress,
  Completed,
}

const operation = {
  status: Status.Pending,
};

if (operation.status === Status.Pending) {
  console.log("Current operation status: ", Status.Pending);
  // Current operation status: 0
}
```

Так само в enum ми можемо, наприклад зберігати статус користувача (ADMIN, GUEST, MODERATOR), або якийсь інший параметр.

А ось так цей код буде скомпільований в js.

```javascript
var Status;
(function (Status) {
    Status[Status["Pending"] = 0] = "Pending";
    Status[Status["InProgress"] = 1] = "InProgress";
    Status[Status["Completed"] = 2] = "Completed";
})(Status || (Status = {}));

var operation = {
    status: Status.Pending,
};
if (operation.status === Status.Pending) {
    console.log("Current operation status: ", Status.Pending);
}
```

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FwlHL2R4uQtM8ZLc66pQA%2Fenum-console2.png?alt=media&#x26;token=5a377c1b-0d3f-4ab6-bca5-c50ed09e72e1" alt="" width="375"><figcaption></figcaption></figure>

## Union Type <a href="#union-type" id="union-type"></a>

**Об'єднання типів (Union Types)** використовують для опису змінних, які можуть мати різні типи. Об'єднання типів позначається символом <mark style="background-color:red;">|</mark> між типами.

```typescript
let value: number | string;
value = 42;     // допустимо, оскільки number
value = "hello"; // допустимо, оскільки string
```

Якщо присвоїти значення іншого типу, то виникне помилка.

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FgSpJpSmZDd9d4F5IKogs%2Funion-type-error.png?alt=media&#x26;token=02373281-1fa0-4f79-a0b9-befdacc93ffa" alt="" width="349"><figcaption></figcaption></figure>

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2Ftat82AHbu9QGl9OvDHH0%2Funion-type-error-2.png?alt=media&#x26;token=67747613-78a2-4301-a378-ade6e5b0b772" alt="" width="375"><figcaption></figcaption></figure>

Коли використовується Union Type як параметр функції, це означає, що функція може приймати аргументи з будь-якого з типів визначених в об'єднанні.

```typescript
function printId(id: number | string) {
    console.log(id);
}

printId(123);    // допустимо
printId("abc");  // допустимо
```

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

Розглянемо приклад функції, яка прийматиме два параметри можливих типів число або рядок. Якщо обидва параметри числа - то функція їх додаватиме, у всіх інших випадках - виконуватиме конкатенацію.

```typescript
function myFunc(value1: number | string, value2: number | string) {
  if (typeof value1 === "number" && typeof value2 === "number") {
    return value1 + value2;
  } else {
    return value1.toString() + value2.toString();
  }
}

console.log("numbers: ", myFunc(1, 2));
console.log("strings: ", myFunc(1, "2"));
```

<figure><img src="https://2122416250-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBlMSwb4UoHEW7y3R9FxZ%2Fuploads%2FWvV5htFEPg4ed0m47CZp%2Funion_add_concat.png?alt=media&#x26;token=c66cc139-1471-49d5-bf38-edbb7e317b6d" alt="" width="375"><figcaption></figcaption></figure>

## Literal Type <a href="#literal-type" id="literal-type"></a>

В TypeScript **Literal Type** - це тип, який використовує конкретне літеральне значення як тип даних. Це означає, що змінна або параметр може приймати лише конкретне значення, яке вказане як літерал. Використання літеральних типів дозволяє зробити типи більш точними та визначити можливі значення для змінних або параметрів функцій.

**Рядкові літерали:**

```typescript
let status: "success" | "error";
status = "success"; // допустимо
status = "error";   // допустимо
status = "pending"; // помилка, так як "pending" не є відомим літералом типу
```

**Числові літерали:**

```typescript
let num: 1 | 2 | 3;
num = 1; // допустимо
num = 2; // допустимо
num = 3; // допустимо
num = 4; // помилка, так як 4 не є відомим літералом типу
```

Літеральні типи корисні при визначенні точних значень, які змінна чи параметр може приймати, і допомагають визначити допустимі варіанти значень в коді, забезпечуючи більшу надійність і контроль.

