masha_codeca – Telegram
masha_codeca
129 subscribers
12 photos
16 videos
1 file
62 links
👋 Привет, друг!
Давайте знакомиться! Меня зовут Маша и я фронтенд разработчик. Работала в таких крупных компаниях как Epam и Yandex, а также в стартапах и веб-студиях. В общем я прошла огонь, воду, «галеры» и бигтехи. 👩‍💻И мне есть, что тебе рассказать. 😏
Download Telegram
Самые полезные операторы TypeScript: typeof и keyof

TypeScript даёт нам два классных оператора, которые делают работу с типами удобнее:

🔹 typeof — позволяет взять тип у уже существующей переменной:


const age = 30;
type AgeType = typeof age; // number


Теперь AgeType будет всегда таким же, как тип переменной age. Это полезно, когда нужно создать новый тип на основе уже объявленных данных.

Другой пример:


onst user = {
name: "Alice",
age: 25,
};

type UserType = typeof user;


Теперь UserType — это { name: string; age: number }, и если user изменится, тип автоматически обновится.

🔹 keyof — даёт список ключей объекта в виде строкового типа:


type UserKeys = keyof UserType; // "name" | "age"


Теперь UserKeys — это "name" | "age", и мы можем использовать это, например, в функции:


function printUserInfo(key: UserKeys) {
console.log(key);
}

printUserInfo("name"); // Работает
// printUserInfo("email"); // Ошибка, такого ключа нет


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

Итог:

typeof помогает взять существующий тип.

keyof позволяет получить список ключей объекта.

Простые, но мощные штуки, которые делают код более надёжным! 🚀
Задача дня

Вот код:


const user = {
id: 1,
name: "Alice",
isAdmin: true,
};

type UserKeys = keyof typeof user;

let key: UserKeys;


Какой тип будет у переменной key?

Ответ
"id" | "name" | "isAdmin"

Если возникли трудности, можно почитать тут:
🔗 https://www.typenoscriptlang.org/docs/handbook/2/keyof-types.html
🔗 https://www.typenoscriptlang.org/docs/handbook/2/typeof-types.html
This media is not supported in your browser
VIEW IN TELEGRAM
Кто сказал, что фастфуд только вредит?!

А если так?)
Задача дня

Что выведет в консоль этот код?


const promise = new Promise((resolve, reject) => {
console.log("Начало");
resolve("Успех");
});

promise
.then((result) => {
console.log(result);
return "Следующий then";
})
.finally(() => {
console.log("Финально");
})
.then((data) => {
console.log(data);
});

console.log("Конец");


Ответ
Начало
Конец
Успех
Финально
Следующий then

💡 Запутался? Почитай подробнее про finally:
👉 https://learn.javanoscript.ru/promise-chaining
1
Задача дня

Что выведет консоль?


const numbers = [1, 2, 3, 4, 5];

const result = numbers.map(num => {
if (num % 2 === 0) {
return num * 2;
}
});

console.log(result);


Ответ
[undefined, 4, undefined, 8, undefined]

📚 Почитать про map можно здесь:
https://learn.javanoscript.ru/array-methods#map
Принципы программирования

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

DRY (Don't Repeat Yourself — Не повторяйся)
Не дублируй код, где можно вынести в общую функцию, модуль или переменную. Чем меньше повторов, тем проще вносить изменения и понимать, что вообще происходит.

KISS (Keep It Simple, Stupid — Не усложняй)
Чем проще код, тем лучше. Если можно сделать что-то понятнее и короче — делай. Не надо усложнять без причины.

Разделяй обязанности (Separation of Concerns, SoC)
Код должен быть разбит на логические куски, каждый из которых отвечает за свою задачу.

Принцип единственной ответственности (SRP)
Каждый модуль, класс или функция должны заниматься чем-то одним. Чем меньше у них причин меняться, тем проще их тестировать и обновлять.

Открыто для расширения, закрыто для модификации (OCP)
Не трогай старый код, если можно добавить что-то новое без его изменения. Для этого есть наследование, интерфейсы и прочие штуки.

Закон Деметры (LoD) — принцип "меньше знаешь, крепче спишь"
Модули (или объекты) не должны лезть внутрь друг друга. Пусть взаимодействуют только по предоставленному API.

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

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

Разработка через тестирование (TDD)
Сначала пиши тесты, потом код. Так ты точно будешь знать, что все работает как надо, и рефакторить код будет проще.

YAGNI (You Aren’t Gonna Need It — Тебе это не понадобится)
Не пиши функционал, который может пригодиться в будущем. Скорее всего, он не пригодится, а вот код засорит.

Соблюдая эти принципы, можно писать чистый, удобный и понятный код, который не стыдно показать коллегам. 🚀
Задача дня

Что выведет в консоль следующий код?


console.log(null || 2 || undefined);
console.log(1 && null && 3);
console.log(!1 || 2 && 3);
console.log(0 ?? 5);
console.log(null ?? 'Привет');


Ответ

2
null
3
0
"Привет"

Если возникли трудности, можно почитать про логические операторы и оператор нулевого слияния тут:
🔗 https://learn.javanoscript.ru/logical-operators
🔗 https://learn.javanoscript.ru/nullish-operators
Задача дня

Что выведет в консоль этот код?


async function foo() {
try {
return await Promise.reject("Ошибка!");
} catch (error) {
console.log("Ошибка поймана:", error);
}
}

foo().then((res) => console.log("Результат:", res));


💡 Запутался? Почитай подробнее про async/await и обработку ошибок:
👉 https://learn.javanoscript.ru/async-await
Задача дня

Что выведет в консоль следующий код?


let a = 1;
let b = 2;

a ??= 10;
b ??= 20;

console.log(a, b);

let c = null;
let d = undefined;

c ??= 15;
d ??= 25;

console.log(c, d);


Ответ

1 2
15 25

Если возникли трудности, можно почитать про оператор нулевого слияния и присваивание через ??= тут:
🔗 https://learn.javanoscript.ru/nullish-operators#operator-nulevogo-prisvaivaniya
Задача дня

Что выведет консоль?


const arr = [10, 20, 30, 40];

const result = arr.reduce((acc, num) => {
if (num > 20) {
acc.push(num / 2);
}
return acc;
}, []);

console.log(result);


Ответ
[15, 20]

📚 Почитать про reduce можно здесь:
https://learn.javanoscript.ru/array-methods#reduce-reduceright
Задача дня

Привет! Давай немного прокачаем мозги перед работой. Сегодня у нас задачка на проверку класса через instanceof.

Что выведет консоль и почему?


class Animal {}
class Dog extends Animal {}

const dog = new Dog();

console.log(dog instanceof Dog);
console.log(dog instanceof Animal);
console.log(dog instanceof Object);
console.log(dog instanceof Array);


Ответ
true
true
true
false

Если что-то неясно, вот статья, которая поможет разобраться:
🔗 https://learn.javanoscript.ru/instanceof

Делись своим ответом в комментариях! 🚀
Задача дня

Привет, друг! Сегодня разберём наследование классов. Готов?

Что выведет консоль и почему?


class Animal {
constructor(name) {
this.name = name;
}

speak() {
return `${this.name} издаёт звук.`;
}
}

class Dog extends Animal {
speak() {
return "Гав-гав!";
}
}

const dog = new Dog("Шарик");

console.log(dog.speak());
console.log(dog.name);


Ответ
"Гав-гав!"
"Шарик"

Если хочешь разобраться глубже, вот полезная статья:
🔗 https://learn.javanoscript.ru/class-inheritance

Жду твои мысли в комментариях! 🚀
Как я впиливала стейт-менеджер и почему это спасло проект

Это, наверное, мой самый большой Pull Request за всё время работы, и он стал идеальным подтверждением того, что стейт-менеджер может очень сильно упростить жизнь и сократить количество кода.

До этого состояние в проекте хранилось через хуки. Сначала это не вызывало проблем – всё было относительно чисто и понятно. Но со временем непредвиденные изменения в бизнес-логике, помноженные на классическое "Это нужно на проде вчера", превратили код в хаос.

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

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

Итог:
Чистая и предсказуемая структура хранения данных
Упрощённые связи между компонентами
Минимум лишнего кода
Гораздо меньше боли при внесении изменений

Вывод: если проект начинает разрастаться, стейт-менеджер – не просто удобство, а необходимость. Лучше внедрить его заранее, чем потом раскапывать горы запутанного кода.
🔥1
Задача дня

В этом коде есть проблема с производительностью.
Как можно его оптимизировать?


import React, { useState } from "react";

function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState("");

function increment() {
setCount(count + 1);
}

function handleChange(event) {
setText(event.target.value);
}

function expensiveCalculation(num) {
console.log("Выполняем тяжелый расчет...");
return num * 2;
}

const result = expensiveCalculation(count);

return (
<div>
<p>Результат: {result}</p>
<button onClick={increment}>+</button>
<input type="text" value={text} onChange={handleChange} />
</div>
);
}

export default App;


Ответ
expensiveCalculation(count) вызывается при каждом ререндере, даже если count не менялся. Нужно мемоизировать его с помощью useMemo: const result = useMemo(() => expensiveCalculation(count), [count]);.

Если возникли сложности, почитай про useMemo и оптимизацию вычислений здесь:
👉 https://ru.react.dev/reference/react/useMemo
Context API vs State Manager: Когда что использовать? 🤔

В React управление состоянием можно реализовать разными способами, и один из частых вопросов — когда хватит Context API, а когда нужен полноценный стейт-менеджер? Давай разберёмся!


🔡ontext API
Context API — это встроенный инструмент React для передачи данных на глубоком уровне вложенности без проброса пропсов.

Когда использовать:

- Простые глобальные состояния (тема, язык, авторизация).
- Данные, которые редко изменяются.
- Небольшие проекты, где дополнительный стейт-менеджер не оправдан.

Минусы Context API:

- Ререндеры: Любое изменение контекста вызывает перерисовку всех потребителей.
- Сложность обновления: Контекст не подходит для часто меняющегося состояния, например, списка товаров в корзине.


🔡tate Manager (Redux, Zustand, Recoil и др.)
Стейт-менеджеры предлагают централизованное хранилище, оптимизированное для обновления состояния.

Когда использовать:

- Большие и сложные приложения с разными источниками состояния.
- Часто изменяемые данные (например, корзина товаров, фильтры, кэш запросов).
- Нужно разделение логики обновления и UI (например, при использовании middleware).

⚡️ Плюсы стейт-менеджеров:

- Оптимизированные обновления (Redux использует селекторы и мемоизацию, Zustand обновляет только затронутые компоненты).
- Гибкость и масштабируемость (можно легко расширять логику, добавлять middleware и асинхронные экшены).


Что выбрать?

Если нужно просто передавать тему, язык или настройки — Context API.
Если требуется сложная логика обновления, кеширование или масштабируемость — State Manager.
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача дня

Какой тип будет у переменной result?


function merge<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}

const result = merge({ name: "Анна" }, { age: 25 });

console.log(result);


Ответ
{ name: string; age: number; }

Если возникли трудности, читай про эту тему здесь:
https://www.typenoscriptlang.org/docs/handbook/2/generics.html

Дженерики + объединение типов = мощь! 🚀 Используй и пиши гибкий код! 🔥
🔡🔡🔡🔡

Написать код — это одно, но надо еще убедиться, что он работает как надо. Мы хоть и не тестировщики, но проверять свой код и даже писать автотесты все равно приходится. Так что базовое понимание тестирования — обязательно. Вот хорошая статья, в которой кратко разбираются все основные виды тестирования, чтобы ты быстро вник и не растерялся, когда тебя спросят об этом на собеседовании. Кстати, это довольно частый вопрос для фронтенд-разработчиков!

📌 https://habr.com/ru/articles/587620/
Please open Telegram to view this post
VIEW IN TELEGRAM
Задача дня

Что выведет консоль?


const words = ["apple", "banana", "cherry"];

const result = words.filter(word => word.length > 5).map(word => word.toUpperCase());

console.log(result);


Ответ
["BANANA", "CHERRY"]

📚 Почитать про filter и map можно здесь:
https://learn.javanoscript.ru/array-methods#filter
https://learn.javanoscript.ru/array-methods#map