Тёмный

TypeScript - фатальные ошибки! 

Как пройти в IT?
Подписаться 34 тыс.
Просмотров 32 тыс.
50% 1

Опубликовано:

 

29 сен 2024

Поделиться:

Ссылка:

Скачать:

Готовим ссылку...

Добавить в:

Мой плейлист
Посмотреть позже
Комментарии : 129   
@it2138
@it2138 2 года назад
Тренажеры HTML Academy (HTML, CSS, JS, React) + Академия + Книга рецептов фронтендера + комьюнити за 99 рублей: boosty.to/how-to-learn-it Какие тренажеры бывают: htmlacademy.ru/courses#fe-start Подписывайтесь: t.me/howToLearnIT ====================== Друзья, в комментариях последнего выпуска развернулись нешуточные баталии! И это круто! Прочитал все споры и претензии с удовольствием. Но сейчас хочу прокомментировать несколько моментов. Претензия #1. Очень много комментаторов отстаивают префикс I в интерфейсах. Тут мне осталось прикрыться стайлгайдом Майкрософта. Пункт 2-ой в стайлгайдах TS github.com/Microsoft/TypeScri... Уже очень давно не видел тайпинги к библиотеками с префиксами в интерфейсах. Остальные же причины уже озвучены в видео и к ним мне добавить нечего. Претензия #2. Ты что дурак? Вместо того, чтобы использовать утилиты для маппинга типа можно использовать наследование. Да, это правда. И мне жаль что в видео тема наследования не была раскрыта. Конечно же можно было бы решить задачу наследованием. Но тайпскрипт на данный момент идет к Mapped Types. 1) Наследование создает самую сильную связь и в программирование есть рекомендация стараться избегать наследования любой ценой, ибо архитектура, построенная на наследование очень тяжело адаптируется к изменениям. Я понимаю, что это еще более холиварная тема. Однако Майкрософт выбрал вектор Mapped Types и если вы почитаете исходный код Ангуляра или того же Тайпскрипта, то повсюду будете встречать именно утилиты вместо наследования. 2) Подход Mapped Types гораздо более гибок нежели наследование. Многие вещи просто нельзя сделать через extend. Собственно это одна из главных причин, почему идут к Mapped Types. К примеру создать интерфейс CarBook у вас просто не получится с наследованием как тут codesandbox.io/s/silly-ritchi... Претензия #3 Утилиты убивают читабельность. Я бы не сказал, что прям так убивают. Но претензия резонна. Проблема в том, что Mapped Types утилиты так выглядят, потому что они дженерики и по-другому проблему было бы не решить (наверное). С другой стороны думаю комьюнити TS просто еще к ним не привыкло. Возможно сейчас стадия неприятия незнакомого, поэтому столько критики. Стоит добавить, что читабельности поможет разбивание типов на подтипы, как вот тут NonAnonymousBook и CarModel codesandbox.io/s/silly-ritchi... Спасибо всем кто оставлял комментарии! Я прям удовольствие получаю, когда читаю все эти споры!
@Eugene.g
@Eugene.g 2 года назад
Сорри, но шо-то ересь какая-то. Pick и пр утилиты с точки зрения читаемости кода - ужас, по-моему они сделаны для того чтобы писать в ФП стиле т.к. в ФП есть and, or типы. Interface существует вообще для другого, это контракт, а не описание типа. Чтобы не повторяться, есть принцип разделения интерфейсов Префикс i ни как не нарушает инкапсуляцию и я не припомню, чтобы хоть раз я переделывал интерфейс в класс По поводу иммутабельности тоже ерунда. Она нужна только если мы пишем в ФП, в ООП мутабильность - благо, просто нужно защищать стейт объекта, например, при помощи геттеров и сеттеров, для этого и нужна инкапсуляция
@mmospanenko
@mmospanenko 2 года назад
Давай больше подобного, не всегда приходится сталкиваться с подобными фишками а без контекста это не так воспринимается с доки - лайк/подписка)
@yurakhomitskyi8762
@yurakhomitskyi8762 2 года назад
Утилиты норм когда у тебя маленькие интерфейсы, но иногда надо 10 ключей взять, и несколько убрать. И эти вложенные утилиты читать сложно. Думаю лучше делать базовые интерфейсы и наследоватся
@yurakhomitskyi8762
@yurakhomitskyi8762 2 года назад
Или разбить на мелкие и потом мержить Interface1 & Interface2
@BOCbMOU
@BOCbMOU 2 года назад
Если тебе необходимо пикнуть аж 10 ключей, то логичнее вынести эти 10 ключей в отдельный интерфейс и унаследовать старый интерфейс от нового. К тому же это в целом уникальная ситуация, когда тебе надо аж 10 ключей пикнуть, подобное на практике я видел всего 1 раз в библиотечном типе. Выглядело ужасно и непонятно зачем, то явный пример говнокода на тс.
@yurakhomitskyi8762
@yurakhomitskyi8762 2 года назад
@@BOCbMOU да хз говно код ли. Бекенд просто странный. У него на разные ендоинты одни и те же модельки имеют разбежности в названиях ключах. И приходилось пикать что-то, выносить в базовые, и короче дубликаты были
@BOCbMOU
@BOCbMOU 2 года назад
@@yurakhomitskyi8762 так это как раз демонстрация того, что проблема в людях, а не инструментах.) Если фронт/бек/оба не смогли в нормальную типизацию, то тут уже какой язык не бери всё будет плохо.)
@kirills4631
@kirills4631 2 года назад
2:20 я бы здесь использовал композицию для интерфейса книги вместо утилити типов для статьи, мне кажется такой подход позволяет лучше проработать интерфейсы бизнес сущностей, повышает читаемость и упрощает расширение
@profesor08
@profesor08 2 года назад
0:50 - 4:00 перезалей, такое говнище нельзя показывать. 4:00 - 5:10 если есть класс, то прекрасно. Но если надо указать какие-то пропсы, то приписка будет либо в начале, либо в конце, либо у интерфейса, либо у функции. Так что эта I это вынужденная мера, чтоб связать визуально две сущности. И пришло это не из .net 7:26 - 7:58 все плохо. Перегрузка нужна для того, чтоб контролировать результат работы функции в зависимости от переданных в нее аргументов. Либо чтоб контролировать передаваемые в нее аргументы и их типы, когда тип последующего аргумента зависит от предыдущего. Если тебе функция ничего не возвращает и не надо контролировать варианты передаваемых аргументов, то перегружать нет смысла.
@Grayt5
@Grayt5 2 года назад
Спорная проблема. А если у нас в интерфейс Book добавятся свойства(например ISBN), которые нужны только для него, то проходить по всем Omit'ам и везде добавлять ещё одно поле?
@Mark1-f2n
@Mark1-f2n 2 года назад
Жду классных примеров с дженериками
@alexperemey6046
@alexperemey6046 Год назад
А я вот пишу I в начале. Но я их пишу и для классов тоже. Потому что "интерфейс" - это понятие логическое. Класс - тоже является интерфейсом. Но у меня классы с I выполняют роль интерфейсов, т.е. они внутри кроме полей и конструктора (и еще возможно геттеров-сеттеров) ничего не содержат.
@TimurShemsedinov
@TimurShemsedinov 2 года назад
строгая типизация в рамках системы типов js, это как связать руки тому, у кого уже ноги переломаны
@TimurShemsedinov
@TimurShemsedinov 2 года назад
1. Не любая конструкция джаваскрипт может быть типизирована тайпскриптом, а то, что это надмножество - это просто маркетинговое вранье. 2. Иногда он неправильно обрабатывает типы и находит ошибки там, где их нет, а пропускает там, где они есть. 3. Основные ошибки они не в системе типов, а в логике программы, в неправильной декомпозиции, в анипаттернах, которые можно без труда покрыть типами и проблема не решится. Разработчики находятся под гипнозом ложной надежности и они меньше заботятся о тестах и ревью кода. 4. В рантайме проверки типов нет, а при взаимодействии клиента и сервера или микросервисов друг с другом все проверки нужно делать руками. 5. Разработчики бегут от сложности предметной области в уютный мирок обсуждения типов в курилках, это достаточно круто звучит все и делает видимость сложного и серьезного дела, чтоб не концентрироваться на душных задачах бизнеса. 6. В нем нет автовывода, а вместо него все много раз дублируется и захламляет код, снижая его читаемость и понятность. 7. Тайпскрипт некоторые идеи передаст в js и отомрет, тогда нужно будет переписывать проекты, как уже было с кофескриптом и многими другим суррогатными языками. 8. Нет четкой спецификации синтаксиса языка, она вообще отсутствует и язык состоит из отдельных фич, которые можно включить и выключить в конфиге. 9. Тестирование решает те же проблемы, но делает это надежнее, потому, что проверяет не только сигнатуры, но и сложное поведение, в том числе асинхронное. 10. Ну и как показал уже Илья в докладах - это экономически не выгодно. Деньги потраченные на юниттесты дают лучший результат.
@СергейЛавров-б9й
@СергейЛавров-б9й 2 года назад
А что вы предлагаете делать вместо TS?
@ApelsinovIvan
@ApelsinovIvan 2 года назад
За то TypeScript позволяет делать оверинженеринг, списывать любое ко-во часов, которое мне не давали списывать на тесты, и чувствовать себя грамотным перцем среди лошков
@СергейЛавров-б9й
@СергейЛавров-б9й 2 года назад
Ты знаешь правило: критикуешь - предлагай
@rudenkom
@rudenkom 2 года назад
@@TimurShemsedinov поддерживаю
@diogen8443
@diogen8443 Год назад
Субьективщина.
@dmitryrockstar
@dmitryrockstar 2 года назад
Пример с Book и Article неправильно подобран, ибо Book и Article фактически две отдельные сущности. Если в сущность Book позже добавятся поля, которые не должны быть в Article то Omit их оставит и это приведет к ошибкам
@spadar1602
@spadar1602 2 года назад
Тоже об этом подумал
@it2138
@it2138 2 года назад
Слушай ну это очень сильно зависит от задачи. Если у тебя магазин продажи публикаций и ты продаёшь книги и статьи. Книга - это pdf, где 300 страниц. Статья - pdf с одной страницей. По сути это одна сущность, поэтому связать Book и Article в этом примере норм как по мне. Очень сомневаюсь, что в онлайн-кинотеатрах фильмы и сериалы не одна и та же сущность. Просто потому что несколько сущностей усложнят поддержку в два раза.
@dmitryrockstar
@dmitryrockstar 2 года назад
@@it2138 в таком случае, зачем 2 типа? Если это магазин публикаций. Делаешь 1 сущность книга и указываешь 1 страницу. Тоже самое фильмы и сериалы. 1 сущность с полем type
@aroundyouaroundme
@aroundyouaroundme 2 года назад
​@@it2138 вот именно, что это зависит от задачи, а ты так расписал в видео как будто все эти композиции типов через Omit, Pick, etc есть всенепременное вселенское благо. Зачастую именно объявление отдельного типа гораздо лучше чем все эти переподвыперты с утилитами типов.
@AgentCooper84
@AgentCooper84 Год назад
@@it2138 тоже заметил, что тут так некорректно пример приведён. Раз эти две сущности связаны, то им нужно сделать один общий интерфейс и его расширять (скажем, какой-нибудь ShelfEntity (название не очень, у меня с этим туго)) - в этот базовый интерфейс положить price и author. Проблема будет тогда, когда в Book будет добавлено поле, которое относится только к Book, но не относится к Article - и всё равно придётся в Omit добавлять такое поле (скажем, появится тип переплёта - typeOfCover - в Article такое поле не нужно) Omit отлично подходит в React, например, когда бы делаем над компонентом какую-нибудь обвязку и какой-нибудь проп в этой обвязке фиксируем - например есть Input с пропами `interface InputProps {onChange: (value) => void; size: InputSize}`, а потом мы делаем FormInput, в котором говорим - что onChange теперь нельзя передавать - `type FormInputProps = Omit` - и то, такой случай не самый лучший, но быстрее ничего не придумал)
@Cons1an1ine
@Cons1an1ine 2 года назад
Совет по наследоваю/выведению в чистом виде может быть крайне опасен, так как зачастую во имя DRY начинает расти зацепление(coupling) всего от всего, хотя семантически сущности абсолютно разные.
@ИмяФамилия-э4ф7в
@ИмяФамилия-э4ф7в 2 года назад
Вот это я тоже хотел отметить. Вообще, так можно отличить того, кто пользуется TS от того, кто "шарит в TS".
@snatvb
@snatvb 2 года назад
coupling -- это связность кода, "низкая связность, высокое зацепление"
@Cons1an1ine
@Cons1an1ine 2 года назад
@@snatvb Это на самом деле беда нашей локализации, как в 2007-ом году перепутали, так оно и неверно качует из перевода в перевод. В оригинале там именно low coupling/high cohesion. Coupling is a measure of how strongly one element is connected to, has knowledge of, or relies on other elements. An element with low (or weak) coupling is not dependent on too many other elements; "too many" is context dependent, but we examine it anyway. These elements include classes, subsystems, systems, and so on. A class with high (or strong) coupling relies on many other classes. ... In terms of object design, cohesion (or more specifically, functional cohesion) is a measure of how strongly related and focused the responsibilities of an element are. An element with highly related responsibilities that does not do a tremendous amount of work has high cohesion. These elements include classes, subsystems, and so on.
@ИмяФамилия-э4ф7в
@ИмяФамилия-э4ф7в 2 года назад
Это всё вопросы терминологии, два человека могут спорить очень долго (и безрезультатно), если под одними терминами они понимают разные вещи. Тут речь идёт о двух вещах: связанности сущностей в логике программы и связанности типов в тайпскрипте. Первое: это как две сущности, описанные типами, связаны в самой программе. Второе - собственно зависимости между типами. Например, есть запись в базе данных какого-нибудь User, есть тип, описывающий её: то поле стринг, это намбер и т.п. Есть, допустим, сущность выдачи каких-то полей юзера, но не всех, а в зависимости от переданных параметров. Очевидно, что мы тип этой выдачи опишем как Partial. Тут вторая сущность связанна с первой, что и отражено в типе. А вот другой пример: тот же юзер как-то отображается в объект на фронте, и имеет те же поля. Есть соблазн связать два типа, и многие так сделают, поля же одинаковые, используем бэковский тип. Но, это два разных типа: тип модели и тип отображения, они, в принципе, не связаны в логике. Ведь фронт в праве как хочет манипулировать данными с API: мапить их, удалять не нужные, добавлять какие хочет, переименовывать. А наш тип к этому не готов, он связан (сцеплен, зацеплен, называйте как хотите) с другим типом, который описывает другую сущность. Ну, или попроще. У нас есть в базе какой-то User и какой-то Car. У обоих есть id, name, createdAt, rating. Мы смотрим, ну все поля одинаковые, бахаем один тип. Но потом машине добавляют поле, мы делаем его в общем типе опциональным, т.к. у юзера его нет. Потом добавляют юзеру, мы снова добавляем опциональное поле... А потом вообще поле с одним именем у машины и у юзера начинает иметь разный тип, почему нет. Наш тип перестаёт вообще что-то типизировать, машине могут залетать поля юзера, и наоборот. Пример, конечно, теоретический. Проблема возникла изначально из-за того, что смешали два типа, хотя они о разных сущностях. Правильно было выделить служебные поля базы данных (id, createdAt) в тип BaseRecord и от него уже наследоваться конкретными типами записей.
@awenn2015
@awenn2015 2 года назад
@@ИмяФамилия-э4ф7в спс, было полезно
@Glotka
@Glotka 2 года назад
А потом эти утилитарные типы превращаются в 3х строчных малочитабельных монстров, где тронь одно и повалится все как в начале видео. Расширить или как то поправить базовые типы будет проблематично т.к. все правки придется вносить и в те же утилиты Pick и Omit, где они не нужны или наоборот нужны. Мое имхо что это все конечно прекрасно, но лучше пусть у меня будет 100500 похожих раздельных типов чем каша из 3-4 статичных типов и утилит.
@alexperemey6046
@alexperemey6046 Год назад
Если у тебя все типы объявлены в одном месте, то не такая уж и каша. Тем более постоянно выводить их не нужно, тебе ж редактор показывает, что в типе. Но да, сильно усложнять, чтобы прямо длинная цепочка утилит была - нечитабельно. Я не знаю, почему автор не упомянул классический вариант - расширение одного интерфейса через другой или их композицию.
@voliansky
@voliansky 2 года назад
Абсолютно не согласен с использованием утилитных типов. Если типы отличаются семантически, то просто необходимо создавать два отдельных типа, даже если на на данный момент все поля одинаковые. Такие типы могут потенциально развиваться отдельно друг от друга и могут сильно отличаться после нескольких релизов. Не стоит плодить ненужные зависимости, когда лень создавать новые типы из-за совпадения полей.
@slavagermonenko2206
@slavagermonenko2206 2 года назад
Простейший пример использование утилиты Omit Например, есть сущность. (например User), у которой много разных полей. Когда мы получаем с бэка список этих сущностей в сервисе и далее передаём их в компоненты/резолверы используем тип User. Однако если нам необходимо написать сервис, который добавлял бы нового юзера. В таком случае нам не нужны поля типо Id, или ещё какие-нибудь служебные поля, которые сами генерятся. В таком случаем аргументом функции добавление юзеров можно сделать что-то типо Omit
@it2138
@it2138 2 года назад
Алярм в выпуске есть фатальный косяк на 3:41 Вот codesandbox.io/s/silly-ritchie-bppkg?file=/src/index.ts _____________ Твой Лайк и подписка спасут интерфейс Cat! Один из моих самых любимых каналов о Фронтенде в telegram: t.me/frontendnoteschannel ________________ 0:00 Пролог 00:51 Миллион и еще 1 одинаковый тип 04:05 Как .Net подпортил нам малину 05:10 Бежим от Function и any 05:45 Извиняюсь за ReturnType 07:26 Тотальная перегрузка 07:58 Закрываем типы на замок 09:17 Резюме ________________ Утилиты TypeScript www.typescriptlang.org/docs/handbook/utility-types.html Почему не стоит использовать префиксы stackoverflow.com/questions/31876947/confused-about-the-interface-and-class-coding-guidelines-for-typescript ________________ Материалы, которые я использовал для подготовки видео: 1) www.typescriptlang.org/ 2) dev.to/busypeoples/notes-on-typescript-returntype-3m5a 3) betterprogramming.pub/7-typescript-common-mistakes-to-avoid-581c30e514d6 4) habr.com/ru/company/tinkoff/blog/521262/ 5) medium.com/nuances-of-programming/%D0%BF%D0%B5%D1%80%D0%B5%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0-%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B9-%D0%B2-typescript-a2027adadeb1 Спасибо авторам! #TypeScript #JavaScript #frontend
@aymkin
@aymkin 2 года назад
Когда уже курсы вашего авторства будут?
@it2138
@it2138 2 года назад
@@aymkin честно говоря я слабо верю в силу курсов и тем более не думаю, что я могу сделать достойные. Поэтому пока мне нравится такой формат выпусков =)
@snatvb
@snatvb 2 года назад
Про ImmuableJS ты не правильно понял. Эта библиотека не для закрытия изменений используется, а для дешевой иммутабельности. Какая самая большая проблема иммутабельности? Она дорогая, как по памяти, так и по времени изменения, ведь требует дополнительных аллокаций. Чтобы изменить массив из 10 000 элементов, тебе нужно скопировать 10 000 элементов - O(n) ImmuableJS дает возможность иммутабельно изменять элемент внутри массива за O(1), там используется хитрая система, зачем нам копировать все, если можно изменить объект, сослаться на него и остальные просто переложить? если у нас программа не изменяемая, то все будет ок, этот принцип работает в языке Closure, на ее принципах и построена эта библиотека
@arsenymedoev5562
@arsenymedoev5562 2 года назад
Хотел увидеть фатальные ошибки TypeScript, а увидел фатальные ошибки разработчиков
@cijic
@cijic Год назад
И этот бред выдаётся за хороший код? Изучите рефакторинг и не страдайте всяким.
@a1ex_sk
@a1ex_sk 2 года назад
Типы и интерфейсы это и технически разные сущности, и главное они разные семантически. Если на проекте используется DI (слабо себе представляю, как на крупном проекте поддерживать качество кодеда без DI), или по любым другим причинам имплементация сервисов отделяется от декларации, то префикс "I", как минимум улучшает читаемость. В любом случае, все зависит от конкретного проекта, принятых стайл-гайдов и прочего, и однозначно заявлять, что префиксы - зло...ну такое
@romanaleksandrovich8219
@romanaleksandrovich8219 2 года назад
а я префикс "I" в имени интерфейса скорее считаю анти-паттерном. Зачем мне знать является ли тип с которым я работаю "абстрактным", контракт которого кто-то реализовал, или я уже напрямую работаю с реальным типом(например классом). Клиентскому коду должно быть в принципе все равно, потребляет ли он интерфейс или класс. Liskov Substitution Principle вот он где. А если в вашем коде вы прямо на уровне нейминга разделяете эти понятия, то вы сразу создаете abstraction leak. Единственное исключение из правил это рефлексия. Если вы активно используете ее в вашем коде, тогда я вижу смысл в разделении реальных и "абстрактных" типов, потому что сама логика вашего кода на этом построена.
@a1ex_sk
@a1ex_sk 2 года назад
@@romanaleksandrovich8219 зависимости должны быть от абстракции. Естественно, в реальности все зависит от проекта, используемого стека и конкретной задачи, но в общем случае, зависимость от реализации - это плохо и, например, на том же код-ревью должно привлечь внимание. Опять таки, это не какое-то жесткое правило. Есть плюсы и минусы. Если вам на конкретном проекте нужна семантика интерфейсов, с учётом особенностей вашего DI (если вы вообще его используете), используйте. Не нужна - конечно нет смысла коллег вводить в заблуждение и усложнять жизнь
@max_mgtow
@max_mgtow 2 года назад
Приветствую бро 🤝👍 Всё очень круто) Всегда жду роликов
@AbraKadabra000
@AbraKadabra000 2 года назад
3:31 жесть нечитабельная. Какой-то недо'хтмл. А главное уде на этом этапе хочется начать поиск альтернативных, простых решений
@ЮрийМусатов-ь3я
@ЮрийМусатов-ь3я 2 года назад
тоже об этом подумал
@it2138
@it2138 2 года назад
Ты прав( Я нашёл очень плохой пример, потому что тут достаточно было сделать просто type NonAnonymousBook = Required. Не знаю как я не досмотрел такой косяк. Но в целом идея комбинировать утилиты правильная (просто не в этом случае, а если б нужно было слить тип с другим типом например) и конечно тогда вопрос читабильности встанет. Как вариант можно разбить тип на несколько подтипов. ____________________________ Воот красивый пример! Допустим вам нужно сделать интерфейс неанонимных книг о машинах, тогда вот какая может быть комбинация: type CarBook = Required & Omit Ну и если с нагромождением утилит падает читабельность, то можно разбить на несколько типов type NonAnonymousBook = Required type CarModel = Omit type CarBook = NonAnonymousBook & CarModel Вот такие задачи, когда нужно связать какие-то части двух типов между собой и как-то их изменить, гораздо более распространены
@AbraKadabra000
@AbraKadabra000 2 года назад
@@it2138 О! Спасибо, полезно!
@it2138
@it2138 2 года назад
Воот-с codesandbox.io/s/silly-ritchie-bppkg?file=/src/index.ts Прошу прощения за косячище =)
@TimurShemsedinov
@TimurShemsedinov 2 года назад
@@it2138 Самое плохое в этом подходе, что типы создаются присвоением и выражениями, пошагово, императивно, процедурно, а не декларативно, как в схемах
@EasyITChannel
@EasyITChannel Год назад
Инструкция как максимально осложнить жизнь новым разрабам после ухода автора кода. Ну или как сделать себя незаменимым на проекте :) Все сказанное интересно в общеобразовательных целях или как челлендж, но на крупном реальном проекте лучше все делать очевидно и чем проще тем лучше. Чтобы для чтения кода не нужно было сидеть в обнимку со справочником по языку. В любом языке много интересных конструкций, которыми вовсе не обязательно пользоваться. Для очевидности кода лучше сделать два интерфейса отличающихся одним полем, чем использовать что-то экзотическое.
@danmax8513
@danmax8513 2 года назад
Требую ещё контента по TypeScript ;)
@Max-nr1bv
@Max-nr1bv 2 года назад
Правило: "никогда не дублируй ...типы" неверно. Даже правило: "никогда не дублируй код" неверно. Вообще слово никогда в программировании нет смысла употреблять в принципе. Плюсы дублирования кода: Меньшее зацепление, легче поддерживать, если сущности изначально разные. Бездумное следование принципу DRY приводит к сложнейшим кускам кода с кучей флагов и условных выражений. Минусы дублирования и так все знают. Я не говорю, что дублировать код нужно всегда, но нужно думать и взвешивать все за и против перед принятием решения
@Max-nr1bv
@Max-nr1bv 2 года назад
Проблема с большим количеством одинаковых типов должна решаться архитектурой приложения, а не утилити типами. Если в проекте большое количество одинаковых типов, это повод задуматься, а что идёт не так. Решая проблему архитектуры сложными типами мы повышаем сложность программы, ее связанность, а главное не решаем корень проблемы
@awenn2015
@awenn2015 2 года назад
Поддерживаю, там явно в проекте кто за ним стоит не с того начал
@akatsukinoyami
@akatsukinoyami Год назад
Второй пример в первой секции (там где Required + Omit), разве не проще сделать так? interface NewInterface extends OldInterface { author: string; } Это и сохранит старые поля, и сделает нужное поле обязательным, но выглядит проще и читабильнее.
@kai.hexendorf
@kai.hexendorf Год назад
Во всех нормальных ооп-языках совсем не случайно присутствует именного перегрузка методов или использование интерфейсов в качестве параметров, а не union-типы. Union-типы почти тоже самое что и any, все они убивают полиморфизм, без которого код не может быть чистым. Особенно "радует" часто используемые типы вроде: string | undefined. А это разве не дублирует логику опционалов? Почему не использовать "const value: string?" тогда. Опциональные цепочки работают на чтение, но почему-то не работают на запись. Стирание типов - это то ещё минное поле. Не ооп, а китайская подделка...
@code-pro
@code-pro Год назад
Про Pick, Omit - бред, на реальном проекте так нельзя делать, ничего плохого нет в дублировании некоторых полей для разных, не связанных сущностей. Не забывай, что помимо того, что сущности расширяются, иногда поля могут и убираться
@TheJabberwahh
@TheJabberwahh Год назад
Всмысле?? Ты просто хотел Нон анонимус бук с обязательным автором? Тогда просто Реквайред на Буке. А ты и пик и омит сгородил. Типичные фронтендеры....
@stasostrin47
@stasostrin47 Год назад
Первые четыре минуты про типы и мапинг какая то хрень... Неужели нельзя сделать базовую абстракцию, а от нее уже клепать книги и неанонимные книги.... Мапинг вообще ужасно плохо читабельная вещь
@QwDragon
@QwDragon 2 года назад
В закреплённом комментарии все ссылки битые... Можно поправить? Особенно codesandbox интересует. Пытался написать под ним, но там моё сообщение видно только мне, так что напишу отдельно ещё раз. А что касается утилитарных типов, то они классные и очень полезны, но стоит посмотреть, как они пишутся и научиться такие же писать самому. Наматывание нескольких типов один поверх другого потенциально опасно, а если ты можешь сам записать в один маппинг (впрочем, в примере с Required это невозможно), то это может помочь. Лично сталкивался с такими проблемами при наматывании типов (и приходилось переписывать): - TS может проверить тип, но не может подсказать: никакого автокомплита и предложений от ide, только постфактум подсветка, накосячил ты или нет. - При совмещении с generic'ом невозможность вывести тип generic'а и скатывание в фоллбэк или unknown, хотя при явном указании всё проверяется корректно. - Невозможность синхронизации типов ключей в сочетании с keyof: по схеме формирования типов два типа имеют одинаковые ключи, но тайпскрипт этого не понимает и отказывается разрешать ключи одного типа для обращения к другому.
@СергейТимушев-н8й
@СергейТимушев-н8й 2 года назад
сколько можно толкать эту имутабельность?) ну это же бред) весь mobx строиться на мутабельности данных. и работает быстрее имутабельного редакса) быстрее и дешевле в плане процессорного времени и объема памяти)
@thekingportalgames8599
@thekingportalgames8599 Год назад
interface Article extends Book ?
@nefertisu6818
@nefertisu6818 2 года назад
Про префикс I абсолютно не согласен, так мы явно видим что ожидаем увидеть ИМЕННО интерфейс или кого-то кто его имплиментирует, это не нарушает инкапсуляцию абсолютно да и слово инкапсуляция здесь абсолютно неприменимо, тут ты скорее хотел затронуть абстракцию
@BOCbMOU
@BOCbMOU 2 года назад
А как отличить интерфес от не интерфейса? type SomeType = ISomeType1 | ISomeType2 - это всё ещё интерфейс или уже нет? type SomeType = { a: number } - это уже интерфейс или нет? interface SomeFunc { (): void } - а это интерфейс или нет? Если его использовать всегда, то зачем он нужен? А если опционально, то удачи выставить границы. Я как-то пытался и в итоге понял, что это не имеет никакого смысла, читабельность это не повышает, а геморрой создаёт. Всё равно подавляющее большинство типов это интерфейсы объектов, а те же функции итак видны по названию. А ещё я не припомню ни один актуальный пекедж с типами, в котором используется I. Может и есть, моя выборка невелика, всё же пакетов как грязи, но не думаю, что найдутся такие из популярных.
@a4y_m5r
@a4y_m5r 2 года назад
Дядь, это не .net и не Java. Какие ещё префиксы I?
@Банки
@Банки Год назад
Не понравилось про обязательное наследование по причине схожести полей. Вредный совет.
@SergioUkrAr
@SergioUkrAr 2 года назад
Супер, контент на высшем уровне, спасибо).
@dotvkab
@dotvkab Год назад
Автор хуже джуна, почитать про умные вещи почитал, а понять их забыл
@СергейПресняков-о4р
Я не учу TypeScript. Зачем я это смотрю?
@keipa-code6112
@keipa-code6112 2 года назад
Использование утилит лучшая практика, чем создавать тип-наследник и в него добавить нужное свойство?
@ИмяФамилия-э4ф7в
@ИмяФамилия-э4ф7в 2 года назад
Тип-наследник? Это как?
@dever4eg
@dever4eg 2 года назад
5:44 Возвращаемое значение функции будет unknown, хотя мы точно знаем что оно будет таким же как у колбека который мы передали. Выглядит так как будто можно было использовать дженерик и все бы прекрасно типизировалось (дженерик прописывать явно при вызове не нужно, он сам распознает исходя из переданного колбека)
@denpol9956
@denpol9956 2 года назад
Удобно читать код с префиксами
@max_mgtow
@max_mgtow 2 года назад
По поводу префиксов просто убил 😆
@xela_8746
@xela_8746 2 года назад
Спасибо за контент...
@edwardfreedom
@edwardfreedom 2 года назад
..... . ... . . .. . . .. .
@m.kozylov
@m.kozylov 2 года назад
Как в первую очередь C# разработчик вот эти утилиты выглядят как какой то костыль, есть же Interface segregation, наследоваие в TS поддерживается, так сделать общий интерфейс IPageCount(свойство pagesCount), и его наследовать для Book\Article. За префикс 'I' для интерфейсов то смысл тут к и в C#, интерфейс это контракт что должно быть в типе(ок, в JS\TS его не обязательно реализовывать) а класс имеет некую реализацию, значение свойств по умолчанию и тп., как бы концептуально смысл разделять эти вещи есть(да и инициализируются они по-разному), но для веб не кажется таким уж критичным. Разве переименовать тип в IDE является какой то проблемой, есть же функции для рефакторинга.
@TheProfessionalGambler
@TheProfessionalGambler 2 года назад
Еще и ошибся в методе интерфейса Cat: *eat(food: Food): Poop*
@bubblesort6368
@bubblesort6368 2 года назад
Проблема все этих утилитных типов и всяческих комбинаций с ними в том, что в последствии черт ногу сломит какую структуру они имеют в итоге. Так как эта структура размазана и перемазана не несколько файлов с иероглифами и тернаринками в них. И как-то ведь живут люди в других яп без этого? В Go, Rust такого нет и люди не жалуются...
@agnia.starovoitova
@agnia.starovoitova 2 года назад
Полезное видео, спасибо Единственное, не раскрыта на мой взляд тема, почему плохо мутировать структуры) Потому что очень важно целостное понимание, почему плохо и к чему это может привести. Будет баг - очень размытая формулировка
@mikhailkh8560
@mikhailkh8560 2 года назад
Так себе видео на самом деле. Что наследование интерфеймов - ну такое, что про префиксы, они наоборот делают проект более читаемым, сразу понимаешь что сюда ты можешь подставить несколлько реализаций. Про мутации - самый яркий пример этой стейт приложения, когда функция не изменяет его а возвращает новый обьект с измененными свойствами. И тогда, если у тебя есть массив этих обьектов то можно посмотреть как изменялись свойства, либо вернуть систему к какому то стейту. Или реализовать функцию отмены ctrl+z. Вообщем есть свои плюсы.
@kai.hexendorf
@kai.hexendorf Год назад
@@mikhailkh8560 Префиксы для интерфейсов - прошлый век, сейчас можно использовать ide, чтобы назначить интерфейсу другой стиль, например, я использую цвет как у класса, но меняю написание интерфейса на курсив. И сразу понятно без всяких префиксов, с чем я имею дело, даже если код написан не мною.
@blacksword3083
@blacksword3083 2 года назад
Почему в примере с executeValidators не дать TS самому за`infer`ить тип?)
@AOne1999
@AOne1999 2 года назад
Зашел чисто лайк поставить за труд. Потом посмотрю)
@Nikitosss91
@Nikitosss91 2 года назад
Чел, сделай курс по ТС , а может и по реакту с редаксом, объясняешь как боженька
@darwim
@darwim 2 года назад
Топчик)
@tanercoder1915
@tanercoder1915 2 года назад
пожалуйста еще такого же контента и много сразу!
@MrWerwoolf
@MrWerwoolf 2 года назад
Лайкнул, подписался, не первое видео смотрю у вас.
@ВикторСмольяков-щ4в
Выпуск огонь! А ещё по этой теме есть?
@hulumulu1108
@hulumulu1108 2 года назад
Больше TS пжлста
@RainbowJet1
@RainbowJet1 2 года назад
Круто, спасибо)
@funnyenglish4330
@funnyenglish4330 2 года назад
Ура! Новое видео🎉
@ivanpavlovschi7092
@ivanpavlovschi7092 2 года назад
Большинство девелоперов использующих префиксы просто выпендриваются намекая на то, что они пришли в мир TS из Java/C#... А все разговоры типа это улучшает читабельность просто отмазки.. Остальная же часть девелоперов использующих префиксы, увидели/услышали где-то что так надо. Автор молодец.
@ПавлоІваницький
@ПавлоІваницький 2 года назад
В джаве никогда не писали префиксы для интерфейсов (было для переменных), в обоих языках любые префиксы давно муветон
@sergeys452
@sergeys452 2 года назад
Какой ужас, вот насмотрятся джуны таких видосов и плачь потом над мерж реквестом. Да и незнающие будут ругать потом тс. Для незнающих ТС: В ТС ничего страшного нет! Его прям максимально приблизили к норм ООП языкам. И как и везде, его можно использовать как попало, а можно красиво и читабельно: interface IArticle { price: number; author?: string; } interface IBook extends IArticle { pagesCount: number; } И всё. Не нужно тут никакие омиты
@ArtemyKairyak
@ArtemyKairyak 2 года назад
в твоем примере не учтено, что свойство автор в статье должно быть обязательным
@sergeys452
@sergeys452 2 года назад
@@ArtemyKairyak так в видео автор необязателен в обеих структурах. См. 1:19
@АлексейБомко-ь1ш
@АлексейБомко-ь1ш 2 года назад
Так! СНАЧАЛА СТАВИМ ЛАЙК, А ПОТОМ СМОТРИМ :)
@zeropoint6130
@zeropoint6130 2 года назад
Просто пишете на JavaScript и не паритесь :D
Далее
Почему?
00:22
Просмотров 150 тыс.
КВН 2024 Встреча выпускников
2:00:41
Самые частые ошибки в TypeScript
9:41
Сколько стоит JavaScript?!?!
30:49
Просмотров 36 тыс.
HTMX заменит Frontend?! WTF?
12:12
Просмотров 112 тыс.
Почему?
00:22
Просмотров 150 тыс.