# Простые типы

## Объявление переменной с определенным типом

Начнем изучение TypeScript с самых простых конструкций. Если вы хотите объявить переменную, в которую можно будет записать любое число (но при этом **только** число), вам нужно воспользоваться встроенным типом `number`. Это будет выглядеть следующим образом:

```typescript
const a: number = 10;
```

Это очень похоже на то, как объявляется переменная в JavaScript:

```javascript
const a = 10;
```

Только добавляется описание типа переменной. Делается это при помощи двоеточия (`:`) и названия типа (`number`). Если попытаться присвоить переменной с типом `number` значение другого типа (например, строки), TypeScript выдаст ошибку во время компиляции:

```typescript
const a: number = "it's a string"; //Error: Type '"it's a string"' is not assignable to type 'number'.(2322)
```

## `number`, `string` и `boolean`

Рассмотри следующие два примитивных типа: 1. `string` - позволяет присваивать любую строку 2. `boolean` - позволяет присваивать любое логическое значение (`true` или `false`)

```typescript
const a: number = 10;
const b: string = "it's a string";
const c: boolean = true;
```

По аналогии с примером для `number`, если мы попытаемся присвоить значение, которое не совместимо с типом, компилятор TypeScript выдаст **ошибку**.

## Массивы

Существует несколько способов, как указать на то, что мы хотим записывать в переменную массив каких-то значений. Первый способ -использовать постфикс `[]` после объявления типа элементов массива.

```typescript
const a: number[] = [1, 2, 3];
```

Второй способ - использовать *интерфейс* `Array` и передать ему в качестве *generic-параметра* тип элементов.

```typescript
const a: Array<number> = [1, 2, 3];
```

Что такое *интерфейс* и *generic-параметры* мы рассмотрим позже. Сейчас важно понимать, что тип для массива можно объявить двумя разными способами и что эти два способа **эквивалентны**.

```typescript
const a: number[] = [1, 2, 3];
const b: Array<number> = a; //Ошибок нет
```

Мы в основном будем пользоваться первым способом.

Все описанные правила для массива применимы не только для `number`, но и для других типов (например, рассмотренные нами `string` и `boolean`).

```typescript
const a: number[] = [1, 2, 3];
const b: string[] = ["1", "2", "3"];
const c: boolean[] = [true, true, false];
```

Рассмотрим несколько важных особенностей массивов:

1. Если хотя бы один элемент присваиваемого массива не соответствует типу элементов массива, то TypeScript выдаст ошибку во время компиляции.

   ```typescript
   const a: number[] = [1, 2, 3, "4"]; //Error: Type 'string' is not assignable to type 'number'.(2322)
   ```
2. Присвоить пустой массив можно любому типу-массиву.

   ```typescript
   const a: number[] = [];
   const b: string[] = [];
   const c: boolean[] = [];
   ```
3. Тип-массив, помимо ограничений на типы элементов этого массива, также определят свойство `length`. Свойство `length` имеет тип `number` и хранит количество элементов в этом массиве.

```typescript
let a: number = 10;
const b: number[] = [10];

console.log(b.length); //1 
console.log(a.length); //Error: Property 'length' does not exist on type 'number'.(2339)

a = b.length; 
const c: boolean = b.length; //Error: Type 'number' is not assignable to type 'boolean'.(2322)
```

## Кортеж (Tuple)

Кортеж - это особый вид массива. Он позволяет строго задать количество элементов массива, а также тип каждого элемента. Например.

```typescript
const a: [number] = [1];
```

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

```typescript
const a: [number] = []; //Error: Property '0' is missing in type '[]' but required in type '[number]'.(2741)
const b: [number] = ["123"]; //Error: Type 'string' is not assignable to type 'number'.(2322)
const c: [number] = [1, 2]; 
/* Error: 
Type '[number, number]' is not assignable to type '[number]'. 
    Types of property 'length' are incompatible.
        Type '2' is not assignable to type '1'.(2322)
*/
```

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

```typescript
const a: [number, number] = [1, 2];
const b: [string, boolean] = ["123", true];
const c: [number[]] = [[1,2,3]];
const e: [[string], [number, number], boolean[]]= [["1"], [100, 100], [true, true, false, true]];
```

## `null` и `undefined`

Без дополнительных настроек значения `null` и `undefined` можно присваивать переменным любого типа.

```typescript
const a: number = null;
const b: number = undefined;
const c: number[] = null;
const d: [string, string] = null;
const e: [string, string] = [null, null];
```

Однако, можно типизировать переменные типами `null` и `undefined`. Таким переменным можно присваивать только два этих типа (почти, но об это в следующей серии).

```typescript
const a: null = null;
const b: undefined = undefined;

const c: null = 1; //Error: Type '1' is not assignable to type 'null'.(2322)
```

## Автоматический вывод типов

В TypeScript любой [литерал](https://ru.wikipedia.org/wiki/Литерал_\(информатика\)) имеет тип. Например

```typescript
10 // имеет тип number
"abav" // string
[1, 2, 3] // number[] а не кортеж [number, number, number]
```

TypeScript автоматически определят тип литерала. При использовании оператора присваивания (`=`) TypeScirpt проверяет соответствие типа правого и левого операнда. Если типы не совместимы, то возникает ошибка компиляции.

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

```typescript
const a = 10; // a: number
const b = a; // b: number
const c = a + b; // c: number
const d = c - 2*a === 0; // d: boolean
```

У механизма автоматического вывода типов есть ряд особенностей. Одна из таких особенностей - различие между массивом и кортежем. Дело в том, что выражение `[1, 2, 3]` имеет тип `number[]`, а не `[number, number, number]`. Соответственно автоматический вывод типов присвоит левой части тип `number[]`. Если мы хотим, чтобы переменная слева была кортежем - нужно явно указывать тип.

```typescript
let a: [number, number];
const b = [1, 2];
a = b; // Error: Type 'number[]' is missing the following properties from type '[number, number]': 0, 1(2739)

const c: [number, number] = [1, 2];
a = c;
```

Однако обратная операция всегда выполнима - значение с типом `[number, number]` всегда можно присвоить в переменную с типом `number[]`.

## P.S.

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

## Задания

* [Задание #1](https://www.typescriptlang.org/play?strictNullChecks=false\&ts=4.1.3#code/PQKgsAUABDWMQgguEEAwgg2EEBwgghEEKwgVDsIIXhAlBxEC3zUHkQAGiiI0D4QQRhBBpECnx2cG4QOqOwCRA0GdBFAR1APCCB+EDQdygMRA0aSCGCQAxgHsAdgGcALlACGARgBcUTQFcAtgCMApgCcoAXjVa9hgExmb69QBs7A00XKDcdfQMAZjM9BwBLTQBzUPCPAwAWM0tbRwBtAF1UiA0IwwBWMwBBBwcDAE8AHjjEpIA+YtL0gDYzPJbkoucwkvdIgHY+3wCgzWoc+wchka7IgA4+hfyC6hq6poH25bTIowAGTetF6jytpZvbq8cdqDzH3KWCr+LIUEhYeDIdDYKAYNASJjUWiMFhsKCcbh8ARCETiKQyeSKCDKE5QGymGDDcZnADcuJs3kJUAAZgZ-No7GTRmUbDEqQAifx0gwAawM7KZqzxWSpeV0DgsdmotPpdgKgrGeN6ovO1HZ53Z8vJk1FADp9WKJXKtcyPDYNqK3vrdXlzl8XlaDeqzpr7ZBcaoABZ2VQ8nx+QLBUI2DJ5KIm37gaCwQB4IAxyIAmEEwOAkWEAAiBYMSkfBMHCqIwAWlUGSh9GYrHYTC4PH4gmEokk0jkCn+sATUEAsiD0MTwrgIHBoXtCHCAQRAoBI03QE+nkGIsTiIO7F8vQFBAIggffHk+nk+EC6FXp9PIA+gS7qF81AANRQcoKsqH33HzwXzy67QWGxxAAUZwAlPeHiPiebLTIGITDKoUR5GcJoHt6T4ZBe0FGEUN53h6CEnuUF4ZLqAAOFjaJ636ctyfLsgBQA)

* [Задание #2](https://www.typescriptlang.org/play?strictNullChecks=false#code/PQKgsAUABDWOgggGEECwgDBCIIVhAqsBwgh+EG4OwgCgYiDaByIFNlAYLwgCg4iDo3aDyIFEoNwgbAhgDRQAjfgGNKUACb9UCQFwg-eqkB8IIEYQQNIgkWFBqY1HRVEWAJEGzLFMqDMWAeEHxdS2AHSQQwSJGEB7AHYBnAC5Q3FAAvFAAZtwANj4ApgDc7t7+giHhUbEJEJ6+AaKhEdHxiTkSqQUZbhDFyQCOAIyp3JnZtQBMqeIA2gAMALrNSQE1AMypNe0A1FD1UFPiDpExXgDmfgAWAyU1ACypAgtLq2uzgp2tvQcr65u1AKx7IcGhwp11vT391UMAbKkvbx9Hs9Xu8+h8bkMAOxjX5PUI1e5wqD-d5vCHTAAcAC4oF4AK6RSJ-cFAA)

* [Пример решения задания #1](https://www.typescriptlang.org/play?strictNullChecks=false\&ts=4.1.3#code/PQKgsAUABDWMQgguEEAwgg2EEBwgVDsIIXhAmHEQQVhBs1B5EABoo9AhEED4QQRhBBpECmwKkcG4QGqGwCRA06aCKAhqAeEED8IGnYlAYiBo0kEMEgBjAPYA7AM4AXKAEMAjAC4oGgK4BbAEYBTAE5QAvFEMAGANyrNugwCZTazU1ABtbfQ1nKB17c1svCHVtPX0AZlNdewBLDQBzKIAiEP1igGt9AoSk330AFlMLGwcAbQBdKOb3VqqfFIBWUwBBe3t9AE8AHkyc3IA+DqKS-XKC7u9kgwA2U2bpvPaXZsWyirXE3oMAdh2g0PCNCka7ewOoZpi4ii6ejf0ADh2TxarQow1Gkz2c1ezU6bhBb2Oy1OZ2qKXcgKszwozSBL2xOMxDnhMNxrTJ0Pc2K6+Opb1h5LOkFAkFg8GQ6CgVDQ4gYFGo9CYLDYDE43D4AiEIgkUlk8kUynOG2sJjMhMcLkunnWvmsASgtzCESiADMSlp4tq9NZ0lBIYViidKpb9fV9cFDRo2h0PrYKKaQuaURdrNs3riKJCKW4KAV3Ksfjrrm67hEvYcAHSZ96xWxkhNWgF03FtYmQkvQmGZ9P0sn4qtHOMMyDOlQAC1sKlKgXd9yi1lqzVSjIgzOgsEAeCB0EiAJhA0FRWOICIABEAIoiI2AYBD5tEYzFYHC4vH4gmEYkk0jkCjHMGnUEAsiC0URsTgIVgYOgv1iAQRAoOIlzRp2XZBRCvJQW0MKJ3HzKAVD8e0lhWaCVBtZoDXuR41WhH0vjhJDXTLaECksBDTgSUAoEARBAX1-f9AP-IQwMVXw2w7UoAH0VVxKIVAggBqKA+iQ9tOzYuCXFg9MtHMaxMgACjcABKITWLYm00KNcTUmaXCW2E9jam4rTDHafjBN0lS+m42p0wAB3MLRW1kxEViUoA)

* [Пример решения задания #2](https://www.typescriptlang.org/play/?strictNullChecks=false#code/PQKgsAUABDWOgggGEECwgDCcIFQQiCA4QQ-CBcOwgCgYiBaByIFFlPoLwgCg4iCCsINVoPIgUSg3CBsCGANFACN+AYwpQAJvwwJAXCD86GQHwggRhBA0iCRYUagyhqOiqIsASIFmWKZUGYsA8IHi4ksAOkghgkSMID2AOwDOAFyhuKABeKABGAAYAbg8fAMEALigAgCcAS28Ac1CoACIARwB3AFM8uL9A4WSAbW8AVwAbRv4atMys-gFPT0aS7m8AXUHcuqaWqBq8vP4AM25G3xLh2IgvSolahoBbARLUkbCaqMHV9zX4wILw3O5V9YSCgCZc8RrI04rHgGZc56gANRQa6AiSOPrZfwAC3ul2BABZcgJwSVIVDQQIak9Bii0bCNgUAKxI0IhMLCY6Dd6fC4EgBsuQp4SpH1J5Mp1Op+MeAHY-gyyWEiWyoEyqczuVcABzJBrNRlcoA)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://race-timo.gitbook.io/typescript/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
