#TypeScript
🚩 Что такое utility types в TypeScript?
Основные Utility Types:
🖇 Partial<T> — делает все свойства необязательными
🖇 Required<T> — делает все свойства обязательными
🖇 Pick<T, K> — выбирает только определенные свойства
🖇 Omit<T, K> — исключает определенные свойства
🖇 Readonly<T> — делает все свойства только для чтения
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
Utility types — это встроенные типы в TypeScript, которые помогают разработчикам быстро изменять и манипулировать существующими типами.
Основные Utility Types:
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤2🔥1
#TypeScript
🚩 Что такое декоратор в TypeScript?
Декоратор - функция с @, которая модифицирует класс, метод, свойство или параметр на этапе инициализации. Простыми словами, они нужны для добавления функциональности без изменения основного кода.
БЕЗ декоратора:
С декоратором:
Суть: декоратор убирает дублирование кода 🎯
Типы декораторов:
• Класса - модифицирует конструктор
• Метода - изменяет поведение метода
• Свойства - добавляет валидацию или логирование
• Параметра - проверяет или преобразует аргументы
Применение:
• Валидация данных (например,
• Логирование, кеширование, авторизация
• Фреймворки (Angular, NestJS)
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
Декоратор - функция с @, которая модифицирует класс, метод, свойство или параметр на этапе инициализации. Простыми словами, они нужны для добавления функциональности без изменения основного кода.
БЕЗ декоратора:
class Calculator {
add(a: number, b: number) {
console.log(`Вызван add: ${a}, ${b}`); // дублируется
return a + b;
}
multiply(a: number, b: number) {
console.log(`Вызван multiply: ${a}, ${b}`); // дублируется
return a * b;
}
}
С декоратором:
@log // логика написана 1 раз
class Calculator {
add(a: number, b: number) { return a + b; }
multiply(a: number, b: number) { return a * b; }
}
Суть: декоратор убирает дублирование кода 🎯
Типы декораторов:
• Класса - модифицирует конструктор
• Метода - изменяет поведение метода
• Свойства - добавляет валидацию или логирование
• Параметра - проверяет или преобразует аргументы
Применение:
• Валидация данных (например,
@MinLength(5)
)• Логирование, кеширование, авторизация
• Фреймворки (Angular, NestJS)
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍3❤1
#TypeScript
🚩 Абстрактный класс vs Интерфейс: В чем разница?
Многие разработчики путают эти концепции, но различия критически важны для правильного дизайна кода
📎 Абстрактный класс - базовый класс, который нельзя инстанцировать напрямую
Ключевые особенности:
- Может содержать реализованные методы и поля
- Использует ключевое слово
- Подходит для общего поведения нескольких классов
- Поддерживает наследование (extends)
Пример на TypeScript:
📎 Интерфейс - контракт, описывающий структуру объекта
Ключевые особенности:
- Описывает только сигнатуры методов (без реализации)
- Класс может реализовывать множество интерфейсов
- Используется для строгого контракта
- Поддерживает множественную реализацию (implements)
Пример на TypeScript:
Когда использовать?
Абстрактный класс:
- Когда у вас есть общая логика для группы классов
- Нужно предоставить базовую реализацию
- Хотите контролировать процесс наследования
Интерфейс:
- Когда нужно определить контракт без реализации
- Требуется множественное наследование поведения
- Хотите обеспечить совместимость между разными классами
Правильный выбор между ними определяет архитектуру вашего приложения
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
Многие разработчики путают эти концепции, но различия критически важны для правильного дизайна кода
Ключевые особенности:
- Может содержать реализованные методы и поля
- Использует ключевое слово
abstract
- Подходит для общего поведения нескольких классов
- Поддерживает наследование (extends)
Пример на TypeScript:
abstract class Animal {
abstract makeSound(): void; // Должен быть реализован
move() {
console.log("Moving..."); // Уже реализован
}
}
class Dog extends Animal {
makeSound() {
console.log("Woof!");
}
}
Ключевые особенности:
- Описывает только сигнатуры методов (без реализации)
- Класс может реализовывать множество интерфейсов
- Используется для строгого контракта
- Поддерживает множественную реализацию (implements)
Пример на TypeScript:
interface Flyable {
fly(): void;
}
class Bird implements Flyable {
fly() {
console.log("Flying!");
}
}
Когда использовать?
Абстрактный класс:
- Когда у вас есть общая логика для группы классов
- Нужно предоставить базовую реализацию
- Хотите контролировать процесс наследования
Интерфейс:
- Когда нужно определить контракт без реализации
- Требуется множественное наследование поведения
- Хотите обеспечить совместимость между разными классами
Абстрактные классы = шаблонное поведение + частичная реализация
Интерфейсы = строгий контракт + гибкость
Правильный выбор между ними определяет архитектуру вашего приложения
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍3❤1
#TypeScript
🚩 Почему any в TypeScript хуже, чем отсутствие типов?
Многие разработчики считают any безобидной "заглушкой" для сложных типов. На самом деле any не просто отключает проверку типов — он активно их ломает, создавая ложное чувство безопасности и распространяя "заражение" по всему коду.
TypeScript с any хуже обычного JavaScript, потому что создает иллюзию типизации. В JavaScript вы знаете, что типов нет, и пишете соответствующие проверки. С any вы думаете, что защищены, но на самом деле беззащитны.
Any — это не "я разберусь с типом позже", это "я сломал систему типов для всех, кто использует этот код". Проблема в том, что any заразен — он распространяется на все взаимодействующие с ним типы.
Как any ломает типизацию:
📎 Проблемы any в типизации:
🟣 Заражение типов — все взаимодействующие типы становятся any
🟣 Отсутствие автодополнения — IDE не может предложить методы и свойства
🟣 Скрытие ошибок — TypeScript не покажет проблемы до runtime
🟣 Ложная безопасность — код выглядит типобезопасным, но не является таковым
Когда любой тип лучше any:
unknown — для данных с неизвестной структурой
object — для объектов без конкретной структуры
Record<string, unknown> — для словарей с неизвестными значениями
Дженерики — для переиспользуемых функций
Union типы — когда знаете возможные варианты
✅ Безопасные практики:
- Включите strict режим и noImplicitAny в tsconfig
- Используйте unknown вместо any для внешних данных
- Создавайте type guards для проверки структуры объектов
- Применяйте утилитарные типы (Partial, Pick, Omit)
❌ Избегайте:
- Использования any как "быстрого решения"
- Передачи any в качестве параметров функций
- Касты через any без веских причин
Any в TypeScript — это не инструмент разработки, это вредитель. Каждый any делает ваш код менее надежным и сложнее в поддержке!
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
Многие разработчики считают any безобидной "заглушкой" для сложных типов. На самом деле any не просто отключает проверку типов — он активно их ломает, создавая ложное чувство безопасности и распространяя "заражение" по всему коду.
TypeScript с any хуже обычного JavaScript, потому что создает иллюзию типизации. В JavaScript вы знаете, что типов нет, и пишете соответствующие проверки. С any вы думаете, что защищены, но на самом деле беззащитны.
Any — это не "я разберусь с типом позже", это "я сломал систему типов для всех, кто использует этот код". Проблема в том, что any заразен — он распространяется на все взаимодействующие с ним типы.
Как any ломает типизацию:
// Плохо - any распространяется как вирус
function processData(data: any) {
return data.someProperty; // Тип результата тоже any!
}
const result = processData(userData); // result: any
const value = result.unknownMethod(); // value: any, ошибка в runtime!
// Хорошо - используйте unknown для неизвестных типов
function processData(data: unknown) {
// Принуждает к проверке типа
if (typeof data === 'object' && data !== null && 'someProperty' in data) {
return (data as {someProperty: string}).someProperty;
}
throw new Error('Invalid data format');
}
Когда любой тип лучше any:
unknown — для данных с неизвестной структурой
object — для объектов без конкретной структуры
Record<string, unknown> — для словарей с неизвестными значениями
Дженерики — для переиспользуемых функций
Union типы — когда знаете возможные варианты
- Включите strict режим и noImplicitAny в tsconfig
- Используйте unknown вместо any для внешних данных
- Создавайте type guards для проверки структуры объектов
- Применяйте утилитарные типы (Partial, Pick, Omit)
- Использования any как "быстрого решения"
- Передачи any в качестве параметров функций
- Касты через any без веских причин
Any в TypeScript — это не инструмент разработки, это вредитель. Каждый any делает ваш код менее надежным и сложнее в поддержке!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤3
#TypeScript
🚩 Почему interface и type в TypeScript НЕ взаимозаменяемы?
Ключевое различие: interface предназначен для описания структуры объектов и может быть расширен другими разработчиками. Type — это алиас для любого типа, он закрыт для расширения после объявления.
Типичная ошибка — использовать type для публичных API:
Правильный подход — interface для расширяемых структур:
📎 Когда использовать каждый:
🟣 Interface — объекты, классы, расширяемые API, библиотеки
🟣 Type — union типы, primitive алиасы, computed типы, закрытые структуры
Уникальные возможности type:
Уникальные возможности interface:
✅ Практические правила:
- Interface для объектов и расширяемых API
- Type для union типов и алиасов
- Interface для библиотек (позволяет пользователям расширять)
- Type для внутренней логики приложения
❌ Избегайте:
- Type для публичных API, которые могут расширяться
- Interface для простых алиасов примитивов
- Смешивания подходов в одном проекте без правил
🔎 🔎 🔎 🔎 🔄
#⃣ Вопрос
#⃣ Новости
#⃣ База вопросов
Ключевое различие: interface предназначен для описания структуры объектов и может быть расширен другими разработчиками. Type — это алиас для любого типа, он закрыт для расширения после объявления.
Типичная ошибка — использовать type для публичных API:
// Плохо - закрытый тип, нельзя расширить
export type UserConfig = {
theme: string;
language: string;
};
// Пользователи НЕ могут добавить свои поля!
// UserConfig & { customField: string } - приходится создавать новый тип
Правильный подход — interface для расширяемых структур:
// Хорошо - открытый для расширения
export interface UserConfig {
theme: string;
language: string;
}
// Пользователи могут легко расширять
declare module 'your-lib' {
interface UserConfig {
customField: string; // Declaration merging!
}
}
Уникальные возможности type:
// Только type может делать union типы
type Status = 'loading' | 'success' | 'error';
// Computed типы на основе других
type UserKeys = keyof User; // 'name' | 'email' | 'id'
// Условные типы
type NonNullable<T> = T extends null | undefined ? never : T;
Уникальные возможности interface:
// Declaration merging - объединение объявлений
interface Window {
myGlobalVar: string;
}
interface Window {
anotherVar: number; // Автоматически объединится!
}
// Расширение через extends (более читаемо чем &)
interface AdminUser extends User {
permissions: string[];
}
- Interface для объектов и расширяемых API
- Type для union типов и алиасов
- Interface для библиотек (позволяет пользователям расширять)
- Type для внутренней логики приложения
- Type для публичных API, которые могут расширяться
- Interface для простых алиасов примитивов
- Смешивания подходов в одном проекте без правил
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤6