progway — программирование, IT
2.61K subscribers
25 photos
1 video
246 links
Чат: @prog_way_chat

Разборы вопросов и задач с собеседований, мысли, полезные материалы и просто вещи, что мне интересны из мира IT

Полезности и навигация в закрепе

По всем вопросам: @denisputnov
Download Telegram
Определяющие тайпгарды

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

Определяющие тайпгарды — это функции, которые позволяют уточнить тип unknown переменной. Сразу рассмотрим пример и рассмотрим следующий интерфейс:

interface User {
name: string;
age: number;
roles: string[];
}


И представим, что в коде у нас есть некоторая переменная с неизвестным типом, которую мы хотим обработать:

const foo: any = ...

if (isUser(foo)) {
// обработать как пользователя
} else {
// обработать как что-то иное
}


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

function isUser(value: unknown): value is User {
const user = value as User;

return user !== null
&& typeof user === 'object'
&& typeof user.name === 'string'
&& typeof user.age === 'number'
&& Array.isArray(user.roles)
&& user.roles?.every(role => typeof role === 'string');
}


Это может выглядеть очень некрасиво, но главное, что работает)

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

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #code #typescript
👍175🔥4🤔1🐳1
JavaScript не в браузере: NodeJS, Deno и Bun

Начать стоит с того, что JavaScript может выполняться далеко не только в браузере. Для этого есть такая штука, как рантайм — это среда выполнения, которая обеспечивает все необходимое для выполнения JavaScript кода: движок языка, API среды и т.д.

Рантаймов несчётном множество, как и всего в мире JS, но в этом поговорим о самых интересных: NodeJS, Deno и Bun

👩‍💻 NodeJS — это рантайм JavaScript, построенный на движке V8 от Google Chrome. Он позволяет выполнять JavaScript-код на сервере. По сути, это почти то же самое, что и выполнять код в браузере, за тем лишь исключением, что NodeJS предоставляет API по работе с файлами, операционной системой, среду исполнения тестов и кучу всего ещё

— NodeJS
сейчас — это основной рантайм для всех серверных решений на JavaScript и TypeScript
npm (Node Package Manager) — это тоже про ноду

👩‍💻 Deno — более новый, чем NodeJS, рантайм, от создателя NodeJS. Deno разработан для того, чтобы устранить некоторые недостатки и ограничения ноды, улучшить безопасность и лучшей поддержкой TypeScript. В целом, всё так и есть, только лично мне субъективно кажется, что Deno почти никто не использует(

👩‍💻 Bun — самый новый из этой тройки инструмент, который разработан для того, чтобы быть самым быстрым и легким в использовании, предлагая ряд улучшений по сравнению с другими инструментами. Bun быстрее запускает код, сильно лучше работает с асинхронными запросами, быстрее устанавливает зависимости... Но ему слишком мало лет, чтобы активно тащить его в прод — пока рановато

Краткий итог:

NodeJS - это зрелая платформа с обширной экосистемой и большим сообществом
Deno - альтернатива NodeJS с улучшенной безопасностью, поддержкой TypeScript и другими плюшками
— Bun - новая и перспективная платформа с упором на скорость и интеграцию различных инструментов


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

Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#theory #javascript #typescript #useful
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥22👍1211🐳1
Составные компоненты

Есть такой паттерн для реакта, который называется Compound Components. Это можно перевести как "составные компоненты"

Смысл этого паттерна заключается в том, что мы можем связать компоненты общим окружением и эффективнее использовать их вместе

То есть мы можем заранее объединить компоненты каким-то контекстом и переиспользовать их, например, через общее пространство имён, в качестве которого чаще всего выступает родительский компонент


Запутались в словах? Лучше посмотреть в коде:

Вот пример прям из доки Ant Design:
import { Layout } from 'antd';

<Layout>
<Layout.Header>Header</Layout.Header>
<Layout.Content>Content</Layout.Content>
<Layout.Footer>Footer</Layout.Footer>
</Layout>


Обратили внимание, как компоненты Header, Content и Footer мы получаем напрямую из компонента Layout? Это и есть пример паттерна Compound Components. Компоненты связаны, а используются они из общего пространства — компонента Layout

Зачем же так сделали? Тут преследуется три цели:
1. Явно показать на уровне нейминга, что использовать Layout.Footer вне Layout не нужно
2. Расшарить общий контекст между всеми компонентами Layout
3. Корректно стилизовать части Layout в зависимости от значения внутри общего контекста

С неймингом и стилями, думаю, всё предельно ясно. Но что насчёт контекста? На самом деле, Layout под собой содержит ещё и LayoutContext, который содержит в себе состояние компонента Sider и распространяет его на все дочерние компоненты. Схематически это выглядит примерно так:

InternalLayout  
└ LayoutContext <-- инициализируем контекст
├ Header
├ Content <-- а в этих компонентах получаем его значение
├ Footer
└ Sider


В итоге получится, что все дочерние компоненты, пытающиеся получить доступ к контексту, без обёртки работать будут криво или и вовсе не будут

С точки зрения типов всё тоже не сложно. Тот же Ant Design делает так:
import InternalLayout, { Content, Footer, Header } from './layout';
import Sider from './Sider';

// получаем тип базового layout компонента
type InternalLayoutType = typeof InternalLayout;

// создаём тип, который определит какие компоненты мы вложим в layout
type CompoundedComponent = InternalLayoutType & {
Header: typeof Header;
Footer: typeof Footer;
Content: typeof Content;
Sider: typeof Sider;
};

// нагло переприсваиваем тип
const Layout = InternalLayout as CompoundedComponent;

// нагло биндим нужные компоненты
Layout.Header = Header;
Layout.Footer = Footer;
Layout.Content = Content;
Layout.Sider = Sider;

// не менее нагло экспортируем как public-api
export default Layout;


Спасибо за прочтение, это важно для меня ❤️

@prog_way_blogчат#web #javascript #typescript #theory #code #react #patterns
👍268🔥5🐳3