React Frontend | YeaHub
3.13K subscribers
237 photos
3 videos
1 file
441 links
Теория, подготовка к интервью и курсы для React разработчиков

YeaHub — это платформа для IT-специалистов, объединяющая обучение, карьерный рост, развитие и сообщество единомышленников.

Платформа: https://yeahub.ru

Для связи: @ruslan_kuyanets
Download Telegram
#typescript

Чем отличается тип unknown от типа any в TypeScript?

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

let data: any = "Hello";
// Ошибка будет только на этапе выполнения, а не при компиляции
console.log(data.toFixed()); // TypeError: data.toFixed is not a function



✔️ Тип unknown — это более безопасная альтернатива. Как и any, он позволяет присваивать переменной любое значение, но при попытке взаимодействия с этой переменной TypeScript требует явных проверок типа. Это защищает программу от неожиданного поведения. Например:

let value: unknown = "Hello";
// TypeScript не позволяет вызывать методы без проверки типа

console.log(value.toFixed()); // Ошибка на этапе компиляции

if (typeof value === "number") {
console.log(value.toFixed()); // Теперь безопасно
}



Таким образом, unknown рекомендуется использовать в ситуациях, когда тип значения заранее неизвестен (например, при работе с пользовательскими вводаами или данными API). Этот тип помогает создавать более безопасный код, в отличие от any, который приводит к ошибкам в неожиданых местах.

Ресурсы для изучения:
📔 Статья
📱 Видео
👉 Новости 👉 Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍93🔥3
#typescript

🔤 Что такое пересечение типов (intersection types) в TypeScript, и как оно используется?

Пересечение типов (intersection types) — это способ объединять два или более типов в один. В отличие от объединения типов (union types), которое позволяет переменной быть одного из нескольких типов, пересечение типов требует, чтобы переменная соответствовала сразу всем объединяемым типам.

Пересечение типов создается с помощью оператора & и используется для описания объектов, которые должны одновременно быть человеком и работником:

interface Person {
name: string;
age: number;
}

interface Employee {
employeeId: number;
position: string;
}

// Пересечение типов Person и Employee
type worker = Person & Employee;
const worker: worker = {
name: "John",
age: 35,
employeeId: 12345,
position: "Developer"
};


Здесь тип worker включает все свойства типа Person и Employee. Объект worker должен содержать как имя и возраст (от Person), так и идентификатор сотрудника и должность (от Employee).


❗️ Важно понимать, что если в объединяемых типах есть противоречивые типы — например, если одно и то же свойство имеет разные типы — TypeScript выдаст ошибку. Рассмотрим пример:

interface Cat {
name: string;
purrs: boolean;
}

interface Dog {
name: string;
barks: boolean;
purrs: number; // Противоречивое свойство
}

// TypeScript выдаст ошибку, так как типы свойства purrs различаются
type Pet = Cat & Dog;



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


Ресурсы для изучения:
📔 Статья
📱 Видео
👉 Новости 👉 Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81🔥1
#typeScript

🔎 Что такое enum в TypeScript и как его использовать?

Enum - это способ создать набор именованных констант в TypeScript.


// Создаём enum со статусами заказа
enum OrderStatus {
New, // 0
Processing, // 1
Shipped, // 2
Delivered // 3
}

// Используем его
let status = OrderStatus.New;

// Проверяем статус
if (status === OrderStatus.New) {
console.log("Новый заказ!");
}

// Можно получить имя по значению
console.log(OrderStatus[2]); // "Shipped"



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


Ресурсы для изучения:

➡️ Вопрос

💬 Новости

🎓 Платформа
Please open Telegram to view this post
VIEW IN TELEGRAM
👍112🔥1
#typescript

TypeScript: основы типизации

TypeScript добавляет к JavaScript статическую типизацию, позволяя обнаруживать ошибки до запуска кода.


Базовые типы

- string: для текста (`let name: string = 'Алексей'`)
- number: для чисел (`let age: number = 25`)
- boolean: для true/false (`let isActive: boolean = true`)
- null/undefined: для отсутствия значения
- any: любой тип (избегайте без необходимости)


Интерфейсы

Интерфейсы определяют структуру объектов:
- Задают обязательные и опциональные (`?`) свойства
- Могут содержать свойства только для чтения (`readonly`)
- Используются для типизации объектов и классов


Type Aliases (Псевдонимы типов)

Создают собственные имена для типов:
- Объединяют типы через | (или) и & (и)
- Ограничивают значения конкретным набором
- В отличие от интерфейсов, нельзя "дополнить" новыми свойствами


Массивы и Кортежи

- Массивы: number[] или Array<string>
- Кортежи: массивы с фиксированным порядком разных типов


Функции

TypeScript позволяет типизировать:
- Параметры функции
- Возвращаемое значение
- Опциональные параметры
- Параметры со значениями по умолчанию


Generics (Обобщения)

Позволяют писать гибкий типобезопасный код:
- Создают универсальные функции и классы
- Сохраняют информацию о типе при работе с разными типами
- Используют синтаксис <T> для обозначения "любого типа"


Enum (Перечисления)

Определяют набор именованных констант:
- Улучшают читаемость кода
- Бывают числовые, строковые и смешанные
- Используются для фиксированных наборов значений


Utility Types

Встроенные типы для трансформации существующих типов:
- Partial<T>: все свойства становятся необязательными
- Required<T>: все свойства обязательные
- Readonly<T>: все свойства только для чтения
- Pick<T, K>: выбирает подмножество свойств
- Omit<T, K>: исключает указанные свойства


Советы для начинающих

1. Строгие проверки: Используйте --strictNullChecks для поиска ошибок
2. Вывод типов: Позволяйте TypeScript определять типы автоматически
3. Избегайте any: Используйте только в крайних случаях
4. Интерфейсы vs типы: Интерфейсы для объектов, типы для функций и объединений
5. IDE: VS Code предоставляет отличные инструменты для работы с TypeScript


Ресурсы для изучения:

💬 Новости

🎓 База вопросов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍112
🎙 Собеседование в компанию Точка

На позицию Middle Frontend Разработчик

Большая часть собеседования состоит из кодинга в перемешку с теоретическими вопросами.

1. В каком порядке будут выведены логи?
console.log('1')
Promise.resolve('2')
.then((res) => {
console.log(res);

Promise.resolve('3')
.then((res) => {
console.log(res);
setTimeout(() => {console.log('4')}, 0);
})
})
.then((res) => console.log(res))
.finally((res) => {
console.log(res);
setTimeout(() => {console.log('5')}, 0);
});
console.log('6');


2. А если изменив первый Promise?
console.log('1')
Promise.reject('2')
.then((res) => {
console.log(res);

Promise.resolve('3')
.then((res) => {
console.log(res);
setTimeout(() => {console.log('4')}, 0);
})
})
.catch((res) => console.log(res))
.then((res) => console.log(res))
.finally((res) => {
console.log(res);
setTimeout(() => {console.log('5')}, 0);
});
console.log('6');


3. Что выведет этот код?
function foo() {
const x = 10;

return {
x: 20,
bar: () => {
console.log(this.x)
},
baz: function() {
console.log(this.x)
}
};
}

const obj1 = foo();

obj1.bar(); // ...
obj1.baz(); // ...

const obj2 = foo.call({ x: 30 });
obj2.bar(); // ..
obj2.baz(); // ...


4. Напиши и типизируй функцию для определения типа фигуры
type Rectangle = {
width: number ;
height: number ;
};

type Circle = {
radius: number;
};

type AvailableFigure = Rectangle | Circle;

function isCircle(figure) {
...
}

function getCircleArea(figure: Circle): number {
return Math.pow(figure.radius, 2) * Math.PI
}

function getRectangleArea(figure: Rectangle): number {
return figure.width * figure.height
}

function getArea(figure: AvailableFigure): number {
return isCircle(figure)
? getCircleArea(figure)
: getRectangleArea(figure);
}


5. Напиши нативный Pick<>
type MyPick<T, U extends keyof T> = {
[key in U]: T[key]
}


Все эти задачи мы разбирали в видео:
- 5 типичных задач по TypeScript для Frontend собеседований
- Разбор задач по Event Loop с собеседований
- 5 типичных задач по JavaScript на собеседовании

#interview
Please open Telegram to view this post
VIEW IN TELEGRAM
7🔥4👍1
#TypeScript

🚩 Как работает strictNullChecks в TypeScript?

Когда включен флаг strictNullChecks в TypeScript, как это влияет на обработку null и undefined значений в коде?

TypeScript не позволяет переменным по умолчанию принимать значения null или undefined, если они не указаны явно в типе.

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


Ключевые особенности strictNullChecks:

1️⃣ Безопасность типов: Переменные определенного типа не могут содержать null или undefined без явного указания

2️⃣ Обязательные проверки: Необходимо проверять значения перед их использованием

3️⃣ Предотвращение ошибок: Помогает избежать классической ошибки "Cannot read property X of null/undefined"

4️⃣ Явная декларация: Требует указывать типы как string | null или number | undefined, если значения могут быть нулевыми


Этот строгий режим проверки значительно повышает надежность кода и позволяет выявлять потенциальные проблемы на этапе компиляции, а не во время выполнения программы.


🔎🔎🔎🔎🔄

#️⃣Вопрос

#️⃣Новости

#️⃣База вопросов
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍3
#TypeScript

🚩Чем отличается тип unknown от типа any в TypeScript?

В TypeScript тип any предоставляет полную свободу для работы с переменной, но при этом теряется всякая защита типов.


let data: any = "Hello";
// Ошибка будет только на этапе выполнения, а не при компиляции
console.log(data.toFixed()); // TypeError: data.toFixed is not a function



Тип unknown — это более безопасная альтернатива.

Как и any, он позволяет присваивать переменной любое значение, но при попытке взаимодействия с этой переменной TypeScript требует явных проверок типа. Это защищает программу от неожиданного поведения:


let value: unknown = "Hello";
// TypeScript не позволит вызвать метод без проверки типа
console.log(value.toFixed()); // Ошибка на этапе компиляции

if (typeof value === "number") {
console.log(value.toFixed()); // Теперь это безопасно
}



Основные отличия:

🖇 any — отключает все проверки типов, ошибки только в runtime

🖇 unknown — требует проверки типов перед использованием, ошибки на этапе компиляции


❗️ unknown рекомендуется когда тип значения заранее неизвестен (например, при работе с пользовательскими вводами или данными API).


🔎🔎🔎🔎🔄

#⃣Вопрос

#⃣Новости

#⃣База вопросов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍61
#TypeScript

🚩Что такое utility types в TypeScript?

Utility types — это встроенные типы в TypeScript, которые помогают разработчикам быстро изменять и манипулировать существующими типами.


Основные Utility Types:

🖇Partial<T> — делает все свойства необязательными

🖇Required<T> — делает все свойства обязательными

🖇Pick<T, K> — выбирает только определенные свойства

🖇Omit<T, K> — исключает определенные свойства

🖇Readonly<T> — делает все свойства только для чтения


🔎🔎🔎🔎🔄

#⃣Вопрос

#⃣Новости

#⃣База вопросов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72🔥1
#TypeScript

🚩Что такое декоратор в TypeScript?

Декоратор - функция с @, которая модифицирует класс, метод, свойство или параметр на этапе инициализации. Простыми словами, они нужны для добавления функциональности без изменения основного кода.

БЕЗ декоратора:
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👍31
#TypeScript

🚩Абстрактный класс vs Интерфейс: В чем разница?

Многие разработчики путают эти концепции, но различия критически важны для правильного дизайна кода


📎Абстрактный класс - базовый класс, который нельзя инстанцировать напрямую

Ключевые особенности:
- Может содержать реализованные методы и поля
- Использует ключевое слово 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👍31
#TypeScript

🚩Почему any в TypeScript хуже, чем отсутствие типов?

Многие разработчики считают 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 в типизации:

🟣Заражение типов — все взаимодействующие типы становятся 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 делает ваш код менее надежным и сложнее в поддержке!


🔎🔎🔎🔎🔄

#⃣Вопрос

#⃣Новости

#⃣База вопросов
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83
#TypeScript

🚩Почему interface и type в TypeScript НЕ взаимозаменяемы?

Ключевое различие: 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!
}
}



📎Когда использовать каждый:

🟣Interface — объекты, классы, расширяемые API, библиотеки
🟣Type — union типы, primitive алиасы, computed типы, закрытые структуры

Уникальные возможности 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
👍105