Модуль 12.6
Итоги курса
Поздравляем с завершением! Полный обзор пройденного материала
Поздравление!
Поздравляю вас с завершением курса по TypeScript! Вы прошли 12 модулей и освоили один из самых популярных и мощных языков программирования в мире. Этоsignificant достижение, которое откроет вам множество возможностей в карьере.
TypeScript — это не просто инструмент, а экосистема, которая продолжает расти и развиваться. Знания, которые вы получили, станут фундаментом для вашего дальнейшего роста.
Модуль 1: Основы TypeScript
В первом модуле мы изучили базовые концепции TypeScript и его отличия от JavaScript.
// Что изучили в Модуле 1:
// 1. Установка и настройка TypeScript
npm install -g typescript
tsc --init
// 2. Базовый синтаксис
let message: string = "Hello, TypeScript!";
const count: number = 42;
const isActive: boolean = true;
// 3. Компиляция
tsc hello.ts // Генерирует hello.js
// 4. Настройка tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"strict": true
}
}
// 5. Различия TypeScript и JavaScript
// - Статическая типизация
// - Проверка типов на этапе компиляции
// - Лучшая поддержка IDE
// - Дополнительные фичи (enum, interface, type)
- Статическая типизация
- Компиляция в JavaScript
- Настройка tsconfig.json
- Интеграция с IDE
Модуль 2: Типы данных и переменные
// Примитивные типы
let str: string = "text";
let num: number = 42;
let bool: boolean = true;
let nothing: null = null;
let undef: undefined = undefined;
// Массивы
let numbers: number[] = [1, 2, 3];
let strings: Array<string> = ["a", "b", "c"];
// Кортежи (tuple)
let tuple: [string, number] = ["Alice", 30];
// Enum
enum Direction {
Up = "UP",
Down = "DOWN",
}
// Union типы
type ID = string | number;
// Literal типы
type Status = "active" | "inactive";
// Any и unknown
let anyValue: any = "anything";
let unknownValue: unknown = "safer";
// Типизация объектов
interface User {
name: string;
age: number;
email?: string; // Опциональное
}
// Type aliases
type Point = {
x: number;
y: number;
};
- Примитивные типы: string, number, boolean, null, undefined
- Массивы и кортежи
- Enum и union типы
- Interface и type aliases
- Опциональные свойства
- Типизированные объекты
Модуль 3: Функции
// Типизация параметров и возвращаемого значения
function add(a: number, b: number): number {
return a + b;
}
// Стрелочные функции
const multiply = (a: number, b: number): number => a * b;
// Опциональные параметры
function greet(name: string, greeting?: string): string {
return `${greeting ?? "Hello"}, ${name}!`;
}
// Параметры по умолчанию
function createUser(name: string, role: string = "user"): User {
return { name, role };
}
// Rest параметры
function sum(...numbers: number[]): number {
return numbers.reduce((acc, n) => acc + n, 0);
}
// Функции как типы
type Callback = (data: string) => void;
function processData(callback: Callback): void {
callback("processed");
}
// Перегрузка функций
function format(input: string): string;
function format(input: number): string;
function format(input: string | number): string {
return String(input);
}
- Типизация параметров и возвращаемых значений
- Опциональные параметры и параметры по умолчанию
- Rest и spread операторы
- Типы функций
- Перегрузка функций
Модуль 4: Объекты и интерфейсы
// Интерфейсы
interface User {
readonly id: number;
name: string;
email: string;
age?: number;
}
// Расширение интерфейсов
interface Admin extends User {
role: "admin";
permissions: string[];
}
// Index signatures
interface Dictionary {
[key: string]: string;
}
// Readonly свойства
interface Config {
readonly apiUrl: string;
readonly timeout: number;
}
// Мерджинг интерфейсов (Declaration Merging)
interface Window {
customProperty: string;
}
// Type assertions
const user = {} as User;
user.name = "Alice";
// Property existence checks
function processUser(user: User) {
if ("age" in user) {
console.log(user.age);
}
}
// Utility типы для объектов
type PartialUser = Partial<User>;
type RequiredUser = Required<User>;
type UserWithoutEmail = Omit<User, "email">;
type UserNameAndEmail = Pick<User, "name" | "email">;
- Определение интерфейсов
- Расширение интерфейсов
- Readonly свойства
- Index signatures
- Declaration merging
- Utility типы: Partial, Required, Pick, Omit
Модуль 5: Классы и ООП
// Объявление класса
class Animal {
// Модификаторы доступа
public name: string;
protected age: number;
private _id: number;
readonly species: string;
constructor(name: string, age: number, species: string) {
this.name = name;
this.age = age;
this.species = species;
this._id = Math.random();
}
// Методы
speak(): string {
return `${this.name} makes a sound`;
}
// Геттеры и сеттеры
get info(): string {
return `${this.name}, ${this.age} years old`;
}
set age(value: number) {
if (value < 0) throw new Error("Age cannot be negative");
this.age = value;
}
}
// Наследование
class Dog extends Animal {
breed: string;
constructor(name: string, age: number, breed: string) {
super(name, age, "Canis familiaris");
this.breed = breed;
}
speak(): string {
return `${this.name} barks`;
}
}
// Абстрактные классы
abstract class Shape {
abstract area(): number;
abstract perimeter(): number;
describe(): string {
return `Area: ${this.area()}, Perimeter: ${this.perimeter()}`;
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
area(): number {
return Math.PI * this.radius ** 2;
}
perimeter(): number {
return 2 * Math.PI * this.radius;
}
}
// Интерфейсы для классов
interface Serializable {
serialize(): string;
}
class UserModel implements Serializable {
constructor(public name: string, public email: string) {}
serialize(): string {
return JSON.stringify({ name: this.name, email: this.email });
}
}
- Модификаторы доступа: public, protected, private
- Readonly свойства
- Наследование (extends)
- Абстрактные классы
- Геттеры и сеттеры
- Реализация интерфейсов (implements)
Модуль 6: Продвинутые типы
// Union и Intersection
type StringOrNumber = string | number;
type Named = { name: string };
type Aged = { age: number };
type Person = Named & Aged;
// Discriminated Unions
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rectangle"; width: number; height: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "rectangle":
return shape.width * shape.height;
}
}
// Type Guards
function isString(value: unknown): value is string {
return typeof value === "string";
}
// Template Literal Types
type EventName = "click" | "scroll" | "mousemove";
type EventHandler = `on${Capitalize<EventName>}`;
// "onClick" | "onScroll" | "onMousemove"
// Conditional Types
type IsString<T> = T extends string ? true : false;
type Test = IsString<"hello">; // true
// Mapped Types
type ReadOnly<T> = { readonly [K in keyof T]: T[K] };
// Utility типы
type Partial<T> = { [K in keyof T]?: T[K] };
type Required<T> = { [K in keyof T]-?: T[K] };
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
type Omit<T, K extends keyof T> = { [P in Exclude<keyof T, K>]: T[P] };
- Union и Intersection типы
- Discriminated Unions
- Type Guards и сужение типов
- Template Literal Types
- Conditional Types
- Mapped Types
- Utility типы
Модуль 7: Дженерики
// Базовые дженерики
function identity<T>(arg: T): T {
return arg;
}
// Ограничения (constraints)
function getLength<T extends { length: number }>(arg: T): number {
return arg.length;
}
// Default параметры
interface ApiResponse<T = unknown> {
data: T;
status: number;
}
// Дженерик интерфейсы
interface Repository<T> {
findById(id: string): Promise<T | null>;
findAll(): Promise<T[]>;
save(entity: T): Promise<void>;
delete(id: string): Promise<void>;
}
// Реализация
class UserRepository implements Repository<User> {
async findById(id: string): Promise<User | null> {
// ...
}
async findAll(): Promise<User[]> {
// ...
}
async save(user: User): Promise<void> {
// ...
}
async delete(id: string): Promise<void> {
// ...
}
}
// Дженерик функции
function map<T, U>(array: T[], fn: (item: T) => U): U[] {
return array.map(fn);
}
// infer в дженериках
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
- Базовые дженерики
- Ограничения (extends)
- Default параметры
- Дженерик интерфейсы и классы
- Utility типы с дженериками
- infer для извлечения типов
Модуль 8: Модули и пространства имён
// ES Modules
// utils.ts
export function formatDate(date: Date): string {
return date.toLocaleDateString();
}
export interface User {
id: number;
name: string;
}
// main.ts
import { formatDate, User } from "./utils";
import type { User } from "./utils"; // Только тип
// Namespace (для совместимости)
namespace Validation {
export interface Validator {
validate(value: string): boolean;
}
export class EmailValidator implements Validator {
validate(value: string): boolean {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
}
}
}
// Использование
const validator = new Validation.EmailValidator();
// Dynamic imports
async function loadModule() {
const module = await import("./heavy-module");
module.doSomething();
}
// Re-export
export { formatDate } from "./utils";
export type { User } from "./utils";
- ES Modules (import/export)
- Type-only импорты
- Re-exports
- Dynamic imports
- Namespace (для legacy кода)
- Module resolution
Модуль 9: Асинхронность
// Промисы (Promises)
function fetchData(): Promise<User> {
return new Promise((resolve, reject) => {
// async operation
resolve({ id: 1, name: "Alice" });
});
}
// Async/Await
async function getUser(): Promise<User> {
const response = await fetch("/api/user");
return response.json();
}
// Обработка ошибок
async function safeGetUser(): Promise<User | null> {
try {
return await getUser();
} catch (error) {
console.error("Failed to fetch user:", error);
return null;
}
}
// Параллельные операции
async function loadDashboard() {
const [users, posts, comments] = await Promise.all([
fetchUsers(),
fetchPosts(),
fetchComments(),
]);
return { users, posts, comments };
}
// Promise.allSettled
async function loadWithFallback() {
const results = await Promise.allSettled([
fetchUsers(),
fetchPosts(),
]);
const users = results[0].status === "fulfilled" ? results[0].value : [];
const posts = results[1].status === "fulfilled" ? results[1].value : [];
return { users, posts };
}
// Async iterators
async function* paginate<T>(url: string): AsyncGenerator<T[]> {
let page = 1;
while (true) {
const response = await fetch(`${url}?page=${page}`);
const data = await response.json();
if (data.length === 0) break;
yield data;
page++;
}
}
- Промисы и их типизация
- Async/Await
- Обработка ошибок
- Параллельные операции
- Promise.all, Promise.allSettled
- Async generators
Модуль 10: Декораторы
// Включение декораторов в tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
// Классовый декоратор
function Sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
@Sealed
class MyClass {
// ...
}
// Методовый декоратор
function Log(
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${propertyKey} with`, args);
return originalMethod.apply(this, args);
};
}
class Calculator {
@Log
add(a: number, b: number): number {
return a + b;
}
}
// Декоратор свойства
function Validate(target: any, propertyKey: string) {
let value: any;
const getter = () => value;
const setter = (newVal: any) => {
if (typeof newVal !== "string") {
throw new TypeError("Must be string");
}
value = newVal;
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
});
}
class User {
@Validate
name!: string;
}
- Классовые декораторы
- Методовые декораторы
- Декораторы свойств
- Декораторы параметров
- Фабрики декораторов
- Метаданные (reflect-metadata)
Модуль 11: Реальные проекты
// Пример: REST API с TypeScript
// Структура проекта:
// src/
// ├── controllers/
// ├── services/
// ├── models/
// ├── middleware/
// ├── routes/
// └── utils/
// controllers/userController.ts
import { Request, Response } from "express";
import { UserService } from "../services/userService";
export class UserController {
constructor(private userService: UserService) {}
async getAll(req: Request, res: Response): Promise<void> {
const users = await this.userService.getAll();
res.json({ success: true, data: users });
}
async getById(req: Request, res: Response): Promise<void> {
const user = await this.userService.getById(req.params.id);
if (!user) {
res.status(404).json({ success: false, error: "Not found" });
return;
}
res.json({ success: true, data: user });
}
}
// services/userService.ts
import { UserRepository } from "../repositories/userRepository";
import { User } from "../models/user";
export class UserService {
constructor(private userRepo: UserRepository) {}
async getAll(): Promise<User[]> {
return this.userRepo.findAll();
}
async getById(id: string): Promise<User | null> {
return this.userRepo.findById(id);
}
}
// Тесты
describe("UserService", () => {
let service: UserService;
let mockRepo: jest.Mocked<UserRepository>;
beforeEach(() => {
mockRepo = {
findAll: jest.fn(),
findById: jest.fn(),
save: jest.fn(),
delete: jest.fn(),
};
service = new UserService(mockRepo);
});
it("should return all users", async () => {
const users = [{ id: "1", name: "Alice" }];
mockRepo.findAll.mockResolvedValue(users);
const result = await service.getAll();
expect(result).toEqual(users);
expect(mockRepo.findAll).toHaveBeenCalled();
});
});
- Архитектура проекта
- Разделение ответственности
- Тестирование
- Документирование
- Деплой
Модуль 12: Инструменты и итоги
// Инструменты, которые мы изучили:
// 1. ESLint — статический анализ кода
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslintplugin
// 2. Prettier — форматирование кода
npm install --save-dev prettier eslint-config-prettier
// 3. Jest — тестирование
npm install --save-dev jest ts-jest @types/jest
// 4. TypeScript — компилятор и type checker
npm install --save-dev typescript
// Полная конфигурация проекта:
{
"scripts": {
"dev": "ts-node-dev --respawn src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix",
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
"test": "jest",
"test:coverage": "jest --coverage",
"typecheck": "tsc --noEmit"
}
}
- ESLint и Prettier
- Jest и тестирование
- Настройка инструментов
- Автоматизация
Шпаргалка по синтаксису TypeScript
// ========== ПРИМИТИВЫ ==========
let str: string = "text";
let num: number = 42;
let bool: boolean = true;
let arr: number[] = [1, 2, 3];
let tuple: [string, number] = ["a", 1];
// ========== ТИПЫ ==========
type ID = string | number;
type Status = "active" | "inactive";
interface User {
id: number;
name: string;
email?: string;
}
// ========== ФУНКЦИИ ==========
function add(a: number, b: number): number {
return a + b;
}
const fn = (x: number): string => String(x);
// ========== КЛАССЫ ==========
class Person {
constructor(
public name: string,
private age: number
) {}
greet(): string {
return `Hello, ${this.name}`;
}
}
// ========== ДЖЕНЕРИКИ ==========
function identity<T>(arg: T): T {
return arg;
}
interface Repo<T> {
get(id: string): T;
}
// ========== UTILITY ТИПЫ ==========
Partial<T> // Все свойства опциональны
Required<T> // Все свойства обязательны
Pick<T, K> // Выбор свойств
Omit<T, K> // Исключение свойств
Record<K, V> // Объект с ключами K и значениями V
Readonly<T> // Все свойства readonly
// ========== TYPE GUARDS ==========
typeof x === "string"
x instanceof Array
"prop" in obj
function isUser(x: any): x is User { ... }
// ========== ASYNC ==========
async function fetchData(): Promise<Data> {
const res = await fetch(url);
return res.json();
}
// ========== ДЕКОРАТОРЫ ==========
function Log(target: any, key: string) {
// ...
}
Чек-лист: что вы должны уметь
Рекомендации по дальнейшему обучению
Немедленно (неделя 1-2)
- Практикуйтесь каждый день
- Создайте личный проект
- Прочитайте TypeScript Handbook
- Настройте IDE
Краткосрочно (месяц 1-3)
- Изучите фреймворк (React/Vue/Angular)
- Освойте тестирование
- Создайте портфолио
- Внесите вклад в Open Source
Среднесрочно (месяц 3-6)
- Изучите архитектурные паттерны
- Освойте DevOps основы
- Получите сертификацию
- Найдите работу/клиента
Долгосрочно (6+ месяцев)
- Станьте мейнтейнером
- Создайте библиотеку
- Менторьте других
- Делитесь знаниями
// Пример: Минимальный проект для портфолио
// src/index.ts
import express from 'express';
import cors from 'cors';
const app = express();
app.use(cors());
app.use(express.json());
interface Todo {
id: string;
text: string;
completed: boolean;
createdAt: Date;
}
let todos: Todo[] = [];
app.get('/api/todos', (req, res) => {
res.json({ success: true, data: todos });
});
app.post('/api/todos', (req, res) => {
const { text } = req.body;
const todo: Todo = {
id: crypto.randomUUID(),
text,
completed: false,
createdAt: new Date(),
};
todos.push(todo);
res.status(201).json({ success: true, data: todo });
});
app.patch('/api/todos/:id', (req, res) => {
const { id } = req.params;
const todo = todos.find(t => t.id === id);
if (!todo) {
return res.status(404).json({ success: false, error: 'Not found' });
}
todo.completed = !todo.completed;
res.json({ success: true, data: todo });
});
app.delete('/api/todos/:id', (req, res) => {
const { id } = req.params;
todos = todos.filter(t => t.id !== id);
res.json({ success: true });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
Проектная деятельность
Лучший способ закрепить знания — создать реальный проект. Вот идеи для проектов разного уровня сложности:
Начальный уровень
- TODO приложение
- Калькулятор
- Погодное приложение
- Список задач
Средний уровень
- Блог платформа
- Чат приложение
- Управление проектами
- Система комментариев
Продвинутый уровень
- E-commerce платформа
- SaaS приложение
- Real-time дашборд
- Микросервисная система
Структура проекта:
my-project/ ├── src/ │ ├── components/ # React/Vue компоненты │ ├── hooks/ # Пользовательские хуки │ ├── services/ # API сервисы │ ├── types/ # TypeScript типы │ ├── utils/ # Утилиты │ └── pages/ # Страницы ├── tests/ │ ├── unit/ # Юнит тесты │ ├── integration/ # Интеграционные тесты │ └── e2e/ # E2E тесты ├── docs/ # Документация ├── .github/workflows/ # CI/CD ├── tsconfig.json ├── package.json └── README.md
Карьерные возможности
TypeScript — один из самых востребованных языков на рынке труда. Вот направления, где знания TypeScript highly valued:
Frontend Developer
Создание пользовательских интерфейсов с React, Vue, Angular. Зарплата: $60K-$120K+
Backend Developer
Серверная разработка на Node.js, NestJS, Express. Зарплата: $70K-$130K+
Full-stack Developer
Комплексная разработка от фронтенда до бэкенда. Зарплата: $80K-$150K+
DevOps Engineer
Автоматизация инфраструктуры с TypeScript. Зарплата: $90K-$160K+
Финальные советы от преподавателя
- Практикуйтесь — теория без практики мертва. Пишите код каждый день.
- Читайте чужой код — лучший способ учиться. Изучайте популярные библиотеки.
- Не бойтесь ошибок — они часть процесса обучения. Каждая ошибка — урок.
- Будьте терпеливы — mastery требует времени. Не ожидайте результатов за неделю.
- Делитесь знаниями — объясняя другим, вы лучше понимаете сами.
- Следите за обновлениями — TypeScript развивается. Будьте в курсе изменений.
- Найдите сообщество — общайтесь с другими разработчиками. Это вдохновляет.
- Наслаждайтесь процессом — программирование должно приносить удовольствие.
Обратная связь и следующие шаги
Если у вас есть вопросы, замечания или предложения по курсу, я всегда рад обратной связи. Вот как вы можете продолжить:
Создавайте проекты, экспериментируйте, ломайте и чините код
Вступайте в TypeScript сообщества, участвуйте в дискуссиях
Обновляйте портфолио, откликайтесь на вакансии
Поздравляем с завершением курса!
Вы прошли 12 модулей и освоили TypeScript с нуля до продвинутого уровня.
Это significant достижение, которое откроет вам множество возможностей в мире разработки.
"TypeScript — это не просто язык программирования, это инструмент, который делает ваш код лучше, безопаснее и проще в поддержке."
Желаю вам успехов в дальнейшем обучении и карьере! Помните: постоянное обучение — ключ к успеху.
Итоги курса
10 вопросов