add typescript

This commit is contained in:
2025-02-28 14:39:31 +03:00
parent 7d94ca6021
commit 99dffd0a1d
135 changed files with 1098 additions and 349 deletions

View File

@@ -0,0 +1,60 @@
---
sidebar_position: 1
---
# Зачем нужен TS
TypeScript — это язык программирования, который расширяет JavaScript, добавляя статическую типизацию и другие возможности.
Вот основные причины, зачем он нужен:
1. **Статическая типизация:**
- TypeScript позволяет определять типы переменных, параметров функций и возвращаемых значений. Это помогает находить ошибки на этапе разработки, а не во время выполнения кода.
- Например, если вы случайно передадите строку вместо числа, TypeScript выдаст ошибку.
2. **Улучшение читаемости и поддержки кода:**
- Типы делают код более понятным и самодокументируемым. Легче понять, какие данные ожидаются и возвращаются в функциях.
- Это особенно полезно в больших проектах или при работе в команде.
3. **Инструменты разработки:**
- TypeScript интегрируется с современными IDE (например, Visual Studio Code), предоставляя автодополнение, навигацию по коду и подсказки на основе типов.
- Это ускоряет разработку и уменьшает количество ошибок.
4. **Совместимость с JavaScript:**
- TypeScript — это надмножество JavaScript, поэтому любой валидный JS-код является валидным TypeScript-кодом.
- Вы можете постепенно внедрять TypeScript в существующие проекты.
5. **Поддержка современных возможностей:**
- TypeScript поддерживает современные функции ES6+ (например, классы, модули, стрелочные функции), даже если целевая среда выполнения (например, старые браузеры) их не поддерживает. TypeScript компилирует их в совместимый код.
6. **Повышение надежности:**
- Статическая типизация и проверка типов снижают вероятность ошибок, связанных с неправильным использованием данных.
- Это особенно важно в больших и сложных приложениях.
7. **Поддержка ООП:**
- TypeScript предоставляет более мощные инструменты для объектно-ориентированного программирования, такие как интерфейсы, абстрактные классы, модификаторы доступа (`public`, `private`, `protected`).
8. **Экосистема и сообщество:**
- TypeScript активно развивается и поддерживается Microsoft. Он широко используется в индустрии, особенно в крупных проектах (например, Angular, React, Node.js).
TypeScript помогает писать более надежный, читаемый и поддерживаемый код, особенно в больших проектах. Он сочетает гибкость JavaScript с преимуществами статической типизации.
TypeScript также включает в себя транспилятор, который преобразует TypeScript-код в JavaScript.
Как работает TypeScript:
1. **Проверка типов:**
- TypeScript сначала проверяет типы в коде. Если есть ошибки (например, передача строки вместо числа), компилятор выдаст ошибку.
2. **Транспиляция:**
- После проверки типов TypeScript преобразует TypeScript-код в JavaScript. При этом он удаляет все типы и аннотации, так как они не нужны в рантайме.
3. **Генерация кода:**
- TypeScript генерирует JavaScript-код, который может быть выполнен в любой среде, поддерживающей JavaScript.
### Babel и TypeScript вместе
Babel и TypeScript могут использоваться вместе. Например:
1. **TypeScript для проверки типов:**
- TypeScript используется только для проверки типов, а транспиляцию выполняет Babel.
- Это позволяет использовать все возможности Babel (например, экспериментальные функции JavaScript).
2. **Babel для транспиляции:**
- Babel может транспилировать TypeScript-код с помощью плагина `@babel/preset-typescripts`. Этот плагин удаляет типы и преобразует код в JavaScript.

View File

@@ -0,0 +1,157 @@
---
sidebar_position: 2
---
# Отличие types от interface
В TypeScript и **type**, и **interface** используются для определения типов данных, но они имеют некоторые различия в синтаксисе, возможностях и использовании.
### 1. Синтаксис
**`type:`**
Используется ключевое слово type для создания псевдонимов типов.
```ts
type User = {
name: string;
age: number;
};
```
**`interface:`**
Используется ключевое слово interface.
```ts
interface User {
name: string;
age: number;
}
```
### 2. Расширение
**`type:`**
Для расширения типов используется оператор & (intersection).
```ts
type Person = {
name: string;
};
type User = Person & {
age: number;
};
```
**`interface:`**
Для расширения интерфейсов используется ключевое слово extends.
```ts
interface Person {
name: string;
}
interface User extends Person {
age: number;
}
```
### 3. Объединение типов
**`type:`**
Может создавать объединения (union) и пересечения (intersection) типов.
```ts
type ID = string | number; // Union type
type Combined = TypeA & TypeB; // Intersection type
```
**`interface:`**
Не поддерживает объединения или пересечения напрямую. Однако можно расширять интерфейсы, чтобы достичь похожего результата.
```ts
interface A {
propA: string;
}
interface B {
propB: number;
}
interface Combined extends A, B {}
```
### 4. Примитивные типы и сложные конструкции
**`type:`**
Может использоваться для определения примитивных типов, union-типов, кортежей и других сложных конструкций.
```ts
type StringOrNumber = string | number;
type Tuple = [string, number];
```
**`interface:`**
Используется только для описания объектов. Не может использоваться для примитивов, union-типов или кортежей.
```ts
// Так нельзя:
interface StringOrNumber = string | number; // Ошибка
```
### 5. Декларативное слияние
**`type:`**
Не поддерживает слияние. Если вы определите два типа с одинаковым именем, это вызовет ошибку.
```ts
type User = { name: string };
type User = { age: number }; // Ошибка: Дубликат идентификатора 'User'
```
**`interface:`**
Поддерживает слияние. Если вы определите два интерфейса с одинаковым именем, они объединятся.
```ts
interface User {
name: string;
}
interface User {
age: number;
}
const user: User = {
name: "John",
age: 30,
};
```
### 6. Использование с классами
**`type:`**
Не может быть реализован классом напрямую.
```ts
type Person = {
name: string;
};
class User implements Person { // Ошибка: Нельзя использовать type для реализации
name: string;
}
```
**`interface:`**
Может быть реализован классом.
```ts
interface Person {
name: string;
}
class User implements Person {
name: string;
}
```
### 7. Производительность
**`type:`**
Может быть менее производительным при работе с большими и сложными типами, так как TypeScript каждый раз вычисляет их.
**`interface:`**
Обычно работает быстрее, так как интерфейсы кэшируются и оптимизируются компилятором.
## Когда использовать type, а когда interface?
- **Используйте `type`, если:**
- Нужно создать union-тип, intersection-тип или кортеж.
- Работаете с примитивными типами.
- Нужна гибкость в определении сложных типов.
- **Используйте `interface`, если:**
- Работаете с объектами и классами.
- Нужно использовать декларативное слияние.
- Хотите, чтобы код был более читаемым и понятным для других разработчиков (интерфейсы часто ассоциируются с ООП).
## Итог
- `type` и `interface` во многом похожи, но имеют свои уникальные особенности.
- `type` более гибок и подходит для сложных типов.
- `interface` лучше подходит для объектов и классов, а также поддерживает слияние.
- В большинстве случаев выбор между ними зависит от предпочтений разработчика и конкретной задачи.

View File

@@ -0,0 +1,222 @@
---
sidebar_position: 3
---
# Utility types
**Utility Types** в TypeScript — это встроенные generic-типы, которые предоставляют удобные способы для преобразования или манипуляции существующими типами. Они упрощают работу с типами, позволяя создавать новые типы на основе существующих без необходимости писать сложные конструкции вручную.
Utility Types часто используются для создания производных типов, таких как частичные объекты, обязательные поля, исключение полей и т.д. Они особенно полезны в больших проектах, где требуется гибкость и повторное использование типов.
## Список популярных Utility Types
### 1. Partial\<T>
Создает тип, в котором все свойства **`T`** становятся необязательными.
```ts
interface User {
name: string;
age: number;
}
type PartialUser = Partial<User>;
// { name?: string; age?: number; }
```
### 2. Required\<T>
Создает тип, в котором все свойства **`T`** становятся обязательными.
```ts
interface User {
name?: string;
age?: number;
}
type RequiredUser = Required<User>;
// { name: string; age: number; }
```
### 3. Readonly\<T>
Создает тип, в котором все свойства **`T`** доступны только для чтения.
```ts
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
// { readonly name: string; readonly age: number; }
```
### 4. Record\<K, T>
Создает тип, представляющий объект, где ключи имеют тип **`K`**, а значения — тип **`T`**.
```ts
type UserRoles = Record<string, string>;
// { [key: string]: string }
const roles: UserRoles = {
admin: "Admin",
user: "User",
};
```
### 5. Pick\<T, K>
Создает тип, выбирая только указанные свойства **`K`** из типа **`T`**.
```ts
interface User {
name: string;
age: number;
email: string;
}
type UserNameAndAge = Pick<User, "name" | "age">;
// { name: string; age: number; }
```
### 6. Omit\<T, K>
Создает тип, исключая указанные свойства **`K`** из типа **`T`**.
```ts
interface User {
name: string;
age: number;
email: string;
}
type UserWithoutEmail = Omit<User, "email">;
// { name: string; age: number; }
```
### 7. Exclude\<T, U>
Исключает из типа **`T`** все типы, которые можно присвоить **`U`**.
```ts
type T = string | number | boolean;
type StringOrNumber = Exclude<T, boolean>;
// string | number
```
### 8. Extract\<T, U>
Извлекает из типа **`T`** только те типы, которые можно присвоить **`U`**.
```ts
type T = string | number | boolean;
type OnlyBoolean = Extract<T, boolean>;
// boolean
```
### 9. NonNullable\<T>
Удаляет `null` и `undefined` из типа **`T`**.
```ts
type T = string | number | null | undefined;
type NonNullableT = NonNullable<T>;
// string | number
```
### 10. ReturnType\<T>
Создает тип, представляющий тип возвращаемого значения функции **`T`**.
```ts
function getUser() {
return { name: "John", age: 30 };
}
type UserReturnType = ReturnType<typeof getUser>;
// { name: string; age: number; }
```
### 11. Parameters\<T>
Создает тип, представляющий кортеж параметров функции **`T`**.
```ts
function add(a: number, b: number) {
return a + b;
}
type AddParams = Parameters<typeof add>;
// [a: number, b: number]
```
### 12. ConstructorParameters\<T>
Создает тип, представляющий кортеж параметров конструктора класса **`T`**.
```ts
class User {
constructor(public name: string, public age: number) {}
}
type UserConstructorParams = ConstructorParameters<typeof User>;
// [name: string, age: number]
```
### 13. InstanceType\<T>
Создает тип, представляющий тип экземпляра класса **`T`**.
```ts
class User {
name: string;
age: number;
}
type UserInstance = InstanceType<typeof User>;
// User
```
### 14. ThisParameterType\<T>
Извлекает тип параметра **`this`** из функции **`T`**.
```ts
function greet(this: { name: string }) {
console.log(`Hello, ${this.name}`);
}
type GreetThisType = ThisParameterType<typeof greet>;
// { name: string }
```
### 15. OmitThisParameter\<T>
Создает тип функции, удаляя параметр **`this`**.
```ts
function greet(this: { name: string }) {
console.log(`Hello, ${this.name}`);
}
type GreetWithoutThis = OmitThisParameter<typeof greet>;
// () => void
```
## Примеры использования Utility Types
#### Пример 1: Создание частичного объекта
```ts
interface User {
name: string;
age: number;
email: string;
}
type PartialUser = Partial<User>;
// { name?: string; age?: number; email?: string; }
```
#### Пример 2: Выбор конкретных свойств
```ts
interface User {
name: string;
age: number;
email: string;
}
type UserNameAndEmail = Pick<User, "name" | "email">;
// { name: string; email: string; }
```
#### Пример 3: Исключение свойств
```ts
interface User {
name: string;
age: number;
email: string;
}
type UserWithoutEmail = Omit<User, "email">;
// { name: string; age: number; }
```
## Итог
**Utility Types** в TypeScript — это мощный инструмент для работы с типами. Они позволяют:
- Упрощать создание новых типов на основе существующих.
- Уменьшать дублирование кода.
- Повышать читаемость и поддерживаемость кода.
Использование **Utility Types** делает TypeScript более гибким и выразительным, особенно в больших проектах.

View File

@@ -0,0 +1,86 @@
---
sidebar_position: 4
---
# Generic types
**Generics (обобщения)** в TypeScript — это механизм, который позволяет создавать универсальные, переиспользуемые компоненты (функции, классы, интерфейсы), которые могут работать с разными типами данных, сохраняя при этом безопасность типов.
## Зачем нужны Generics?
- **Повторное использование кода:** Generics позволяют писать универсальные функции и классы, которые могут работать с любыми типами.
- **Безопасность типов:** Generics сохраняют информацию о типах, что помогает избежать ошибок на этапе компиляции.
- **Гибкость:** Generics позволяют создавать компоненты, которые могут адаптироваться к разным типам данных.
## Примеры использования Generics
### 1. Функции с Generics
```ts
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("Hello"); // Тип: string
let output2 = identity<number>(42); // Тип: number
```
**`T`** — это обобщенный тип (type parameter), который заменяется на конкретный тип при вызове функции.
### 2. Классы с Generics
```ts
class Box<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
let box1 = new Box<string>("Hello");
let box2 = new Box<number>(42);
```
Класс **`Box`** может работать с любым типом данных, переданным в **`T`**.
### 3. Интерфейсы с Generics
```ts
interface Pair<T, U> {
first: T;
second: U;
}
let pair: Pair<string, number> = { first: "Age", second: 30 };
```
Интерфейс **`Pair`** может работать с двумя разными типами (**`T`** и **`U`**).
### 4. Ограничения Generics (Constraints)
Иногда нужно ограничить типы, которые можно передать в Generics. Для этого используется ключевое слово **`extends`**.
```ts
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(arg: T): void {
console.log(arg.length);
}
logLength("Hello"); // ОК, у строки есть свойство length
logLength([1, 2, 3]); // ОК, у массива есть свойство length
logLength(42); // Ошибка: у числа нет свойства length
```
### 5. Generics по умолчанию
Можно указать тип по умолчанию для Generics, если тип не был передан явно.
```ts
function createArray<T = string>(length: number, value: T): T[] {
return Array(length).fill(value);
}
let strings = createArray(3, "x"); // string[]
let numbers = createArray<number>(3, 42); // number[]
```
## Преимущества Generics
- **Универсальность:** Generics позволяют писать код, который работает с разными типами.
- **Безопасность типов:** TypeScript проверяет типы на этапе компиляции, что помогает избежать ошибок.
- **Читаемость:** Generics делают код более выразительным и понятным.

View File

@@ -0,0 +1,113 @@
---
sidebar_position: 5
---
# Type guards
**Type Guards (защитники типов)** в TypeScript — это механизм, который позволяет сужать тип переменной внутри блока кода на основе проверки условий. Это помогает TypeScript лучше понимать, с каким типом данных он работает, и обеспечивает безопасность типов.
## Зачем нужны Type Guards?
- **Сужение типов:** TypeScript может автоматически определять тип переменной внутри блока кода после проверки.
- **Безопасность типов:** Type Guards помогают избежать ошибок, связанных с неправильным использованием типов.
- **Улучшение читаемости:** Код становится более понятным, так как явно указываются условия для работы с разными типами.
## Основные виды Type Guards
### 1. `typeof`
Проверяет тип примитивных значений (string, number, boolean, symbol, undefined, object, function).
```ts
function printValue(value: string | number) {
if (typeof value === "string") {
console.log(value.toUpperCase()); // Тип value: string
} else {
console.log(value.toFixed(2)); // Тип value: number
}
}
```
### 2. `instanceof`
Проверяет, является ли объект экземпляром определенного класса.
```ts
class Dog {
bark() {
console.log("Woof!");
}
}
class Cat {
meow() {
console.log("Meow!");
}
}
function makeSound(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark(); // Тип animal: Dog
} else {
animal.meow(); // Тип animal: Cat
}
}
```
### 3. Проверка на `null` или `undefined`
Позволяет исключить `null` или `undefined` из типа.
```ts
function printLength(value: string | null) {
if (value !== null) {
console.log(value.length); // Тип value: string
}
}
```
### 4. Пользовательские Type Guards
Функции, которые возвращают **`boolean`** и помогают TypeScript сузить тип.
```ts
interface Bird {
fly(): void;
}
interface Fish {
swim(): void;
}
function isFish(pet: Bird | Fish): pet is Fish {
return (pet as Fish).swim !== undefined;
}
function move(pet: Bird | Fish) {
if (isFish(pet)) {
pet.swim(); // Тип pet: Fish
} else {
pet.fly(); // Тип pet: Bird
}
}
```
Обратите внимание на синтаксис **`pet is Fish`**. Это указывает TypeScript, что если функция возвращает **`true`**, то **`pet`** имеет тип **`Fish`**.
### 5. Проверка свойств объекта
Позволяет сузить тип на основе наличия определенного свойства.
```ts
interface Car {
drive(): void;
}
interface Boat {
sail(): void;
}
function move(vehicle: Car | Boat) {
if ("drive" in vehicle) {
vehicle.drive(); // Тип vehicle: Car
} else {
vehicle.sail(); // Тип vehicle: Boat
}
}
```
## Итог
**Type Guards** — это мощный инструмент TypeScript для работы с типами. Они позволяют:
- Сужать типы на основе условий.
- Повышать безопасность кода.
- Делать код более читаемым и выразительным.
Используйте **Type Guards**, чтобы TypeScript лучше понимал ваши намерения и помогал избегать ошибок.

View File

@@ -0,0 +1,97 @@
---
sidebar_position: 6
---
# Enums и as const
**Enum (перечисления)** в TypeScript — это способ определения набора именованных констант. Enums полезны, когда нужно работать с набором связанных значений, которые имеют смысл только в контексте друг друга.
## Пример Enum
```ts
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
let move: Direction = Direction.Up;
console.log(move); // "UP"
```
## Особенности Enum
### 1. Числовые Enums:
Если значения не указаны явно, TypeScript автоматически присваивает числа, начиная с 0.
```ts
enum Status {
Pending, // 0
Approved, // 1
Rejected, // 2
}
```
### 2. Строковые Enums:
Каждое значение должно быть явно указано.
```ts
enum Direction {
Up = "UP",
Down = "DOWN",
}
```
### 3. Гетерогенные Enums:
Можно смешивать строковые и числовые значения (но это не рекомендуется).
```ts
enum Mixed {
Yes = 1,
No = "NO",
}
```
## Проблемы с Enum
- **Генерируют дополнительный код:** Enums компилируются в JavaScript-объекты, что может увеличить размер кода.
- **Не всегда интуитивно понятны:** Например, числовые Enums могут быть неочевидными.
- **Сложности с деревомизацией (tree-shaking):** Enums могут мешать оптимизации кода при сборке.
### Замена Enum с помощью `as const`
В TypeScript можно использовать объекты с **`as const`**, чтобы создать тип, аналогичный **Enum**, но без его недостатков.
```ts
const Direction = {
Up: "UP",
Down: "DOWN",
Left: "LEFT",
Right: "RIGHT",
} as const;
type Direction = typeof Direction[keyof typeof Direction];
let move: Direction = Direction.Up;
console.log(move); // "UP"
```
### Преимущества `as const`:
- **Без дополнительного кода:** **`as const`** не генерирует дополнительный код в JavaScript.
- **Иммутабельность:** Значения становятся read-only.
- **Деревоизация:** Легче оптимизировать при сборке.
- **Гибкость:** Можно использовать строки, числа и другие типы.
### Пример с числовыми значениями:
```ts
const Status = {
Pending: 0,
Approved: 1,
Rejected: 2,
} as const;
type Status = typeof Status[keyof typeof Status];
let currentStatus: Status = Status.Approved;
console.log(currentStatus); // 1
```
## Итог
- **Enum** — это классический способ определения набора констант, но он имеет недостатки.
- **`as const`** — это современная альтернатива, которая более гибкая и эффективная.
Используйте **`as const`**, если хотите избежать недостатков Enum и сделать код более легковесным и оптимизированным.

View File

@@ -0,0 +1,7 @@
{
"label": "Typescript",
"position": 4,
"link": {
"type": "generated-index"
}
}