Введение
В этой статье мы рассмотрим основы TypeScript - языка программирования, который расширяет возможности JavaScript добавлением статической типизации. Вы узнаете о преимуществах использования TypeScript, его основных концепциях и лучших практиках разработки.
Что такое TypeScript?
Основные концепции
Особенности языка
- Статическая типизация
- Совместимость с JavaScript
- Объектно-ориентированные возможности
- Поддержка современных возможностей ECMAScript
Преимущества использования
- Раннее обнаружение ошибок
- Улучшенная поддержка IDE
- Лучшая документация кода
- Безопасное рефакторирование
Начало работы
1. Установка и настройка
Установка TypeScript
1
2
| npm install -g typescript
tsc --init
|
Конфигурация проекта
1
2
3
4
5
6
7
8
9
10
| {
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
|
2. Основные типы
Примитивные типы
1
2
3
4
5
6
7
8
9
10
11
12
| // Строки
let name: string = 'John';
// Числа
let age: number = 25;
// Логические значения
let isActive: boolean = true;
// Null и Undefined
let empty: null = null;
let notDefined: undefined = undefined;
|
Сложные типы
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| // Массивы
let numbers: number[] = [1, 2, 3];
let strings: Array<string> = ['a', 'b', 'c'];
// Кортежи
let tuple: [string, number] = ['hello', 42];
// Объекты
let user: {
name: string;
age: number;
} = {
name: 'John',
age: 25
};
|
Интерфейсы и типы
1. Интерфейсы
Определение интерфейсов
1
2
3
4
5
6
7
8
9
10
11
12
| interface User {
name: string;
age: number;
email?: string; // Опциональное свойство
readonly id: number; // Только для чтения
}
const user: User = {
id: 1,
name: 'John',
age: 25
};
|
Расширение интерфейсов
1
2
3
4
5
6
7
8
9
10
11
12
| interface Animal {
name: string;
}
interface Dog extends Animal {
breed: string;
}
const dog: Dog = {
name: 'Rex',
breed: 'German Shepherd'
};
|
2. Type Aliases
Определение типов
1
2
3
4
5
6
7
8
| type Point = {
x: number;
y: number;
};
type ID = string | number;
type Callback = (data: string) => void;
|
Объединение типов
1
2
3
4
5
6
7
8
9
| type Bird = {
fly(): void;
};
type Fish = {
swim(): void;
};
type Pet = Bird | Fish; // Union type
|
Классы
1. Основы классов
Определение класса
1
2
3
4
5
6
7
8
9
10
11
12
13
| class Animal {
private name: string;
protected age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public getName(): string {
return this.name;
}
}
|
Наследование
1
2
3
4
5
6
7
8
9
10
11
12
| class Dog extends Animal {
private breed: string;
constructor(name: string, age: number, breed: string) {
super(name, age);
this.breed = breed;
}
public bark(): void {
console.log('Woof!');
}
}
|
2. Модификаторы доступа
Области видимости
1
2
3
4
5
6
| class Example {
public publicField: string; // Доступно везде
private privateField: string; // Только внутри класса
protected protectedField: string; // Внутри класса и наследников
readonly readonlyField: string; // Только для чтения
}
|
Generics
1. Основы Generics
Функции с Generic
1
2
3
4
5
6
| function identity<T>(arg: T): T {
return arg;
}
const result = identity<string>('hello');
const number = identity(42); // Автоматический вывод типа
|
Интерфейсы с Generic
1
2
3
4
5
6
7
8
9
10
11
12
| interface Container<T> {
value: T;
getValue(): T;
}
class NumberContainer implements Container<number> {
constructor(public value: number) {}
getValue(): number {
return this.value;
}
}
|
2. Ограничения Generic
Extends
1
2
3
4
5
6
7
8
9
10
11
| interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(arg: T): void {
console.log(arg.length);
}
logLength('hello'); // OK
logLength([1, 2, 3]); // OK
logLength({ length: 5 }); // OK
|
Декораторы
1. Классы и методы
Декоратор класса
1
2
3
4
5
6
7
8
9
10
| function logger(constructor: Function) {
console.log('Class created:', constructor.name);
}
@logger
class Example {
constructor() {
console.log('Constructor called');
}
}
|
Декоратор метода
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function(...args: any[]) {
console.log(`Calling ${propertyKey} with:`, args);
return original.apply(this, args);
};
}
class Calculator {
@log
add(a: number, b: number): number {
return a + b;
}
}
|
Утилиты типов
1. Встроенные утилиты
Partial и Required
1
2
3
4
5
6
7
8
9
10
11
| interface User {
name: string;
age: number;
email: string;
}
// Все поля становятся опциональными
type PartialUser = Partial<User>;
// Все поля становятся обязательными
type RequiredUser = Required<User>;
|
Pick и Omit
1
2
3
4
5
| // Выбрать определенные поля
type UserBasicInfo = Pick<User, 'name' | 'age'>;
// Исключить определенные поля
type UserWithoutEmail = Omit<User, 'email'>;
|
Асинхронное программирование
1. Промисы
Типизация промисов
1
2
3
4
5
6
7
8
9
| function fetchUser(): Promise<User> {
return fetch('/api/user')
.then(response => response.json());
}
async function getUser(): Promise<User> {
const user = await fetchUser();
return user;
}
|
2. Async/Await
Обработка ошибок
1
2
3
4
5
6
7
8
9
10
11
| async function handleData(): Promise<void> {
try {
const response = await fetch('/api/data');
const data: ApiResponse = await response.json();
processData(data);
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
}
}
}
|
Модули
1. Импорт и экспорт
Экспорт типов и интерфейсов
1
2
3
4
5
6
7
8
9
10
11
12
| // types.ts
export interface User {
id: number;
name: string;
}
export type UserRole = 'admin' | 'user';
// Экспорт по умолчанию
export default class UserService {
// ...
}
|
Импорт
1
2
3
4
5
6
7
8
| import UserService, { User, UserRole } from './types';
const user: User = {
id: 1,
name: 'John'
};
const role: UserRole = 'admin';
|
Заключение
TypeScript предоставляет мощные инструменты для создания надежных и масштабируемых приложений. Начните с основ и постепенно изучайте более сложные концепции. Практика и работа над реальными проектами помогут вам стать опытным TypeScript-разработчиком.
Полезные ресурсы