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

  Рет қаралды 32,507

Как пройти в IT?

Как пройти в IT?

Күн бұрын

Пікірлер: 129
@Howtogoit
@Howtogoit 3 жыл бұрын
Тренажеры 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... Спасибо всем кто оставлял комментарии! Я прям удовольствие получаю, когда читаю все эти споры!
@Howtogoit
@Howtogoit 3 жыл бұрын
Алярм в выпуске есть фатальный косяк на 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 3 жыл бұрын
Когда уже курсы вашего авторства будут?
@Howtogoit
@Howtogoit 3 жыл бұрын
@@aymkin честно говоря я слабо верю в силу курсов и тем более не думаю, что я могу сделать достойные. Поэтому пока мне нравится такой формат выпусков =)
@dmitryrockstar
@dmitryrockstar 3 жыл бұрын
Пример с Book и Article неправильно подобран, ибо Book и Article фактически две отдельные сущности. Если в сущность Book позже добавятся поля, которые не должны быть в Article то Omit их оставит и это приведет к ошибкам
@spadar1602
@spadar1602 3 жыл бұрын
Тоже об этом подумал
@Howtogoit
@Howtogoit 3 жыл бұрын
Слушай ну это очень сильно зависит от задачи. Если у тебя магазин продажи публикаций и ты продаёшь книги и статьи. Книга - это pdf, где 300 страниц. Статья - pdf с одной страницей. По сути это одна сущность, поэтому связать Book и Article в этом примере норм как по мне. Очень сомневаюсь, что в онлайн-кинотеатрах фильмы и сериалы не одна и та же сущность. Просто потому что несколько сущностей усложнят поддержку в два раза.
@dmitryrockstar
@dmitryrockstar 3 жыл бұрын
@@Howtogoit в таком случае, зачем 2 типа? Если это магазин публикаций. Делаешь 1 сущность книга и указываешь 1 страницу. Тоже самое фильмы и сериалы. 1 сущность с полем type
@aroundyouaroundme
@aroundyouaroundme 3 жыл бұрын
​@@Howtogoit вот именно, что это зависит от задачи, а ты так расписал в видео как будто все эти композиции типов через Omit, Pick, etc есть всенепременное вселенское благо. Зачастую именно объявление отдельного типа гораздо лучше чем все эти переподвыперты с утилитами типов.
@AgentCooper84
@AgentCooper84 Жыл бұрын
@@Howtogoit тоже заметил, что тут так некорректно пример приведён. Раз эти две сущности связаны, то им нужно сделать один общий интерфейс и его расширять (скажем, какой-нибудь 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 3 жыл бұрын
Совет по наследоваю/выведению в чистом виде может быть крайне опасен, так как зачастую во имя DRY начинает расти зацепление(coupling) всего от всего, хотя семантически сущности абсолютно разные.
@ИмяФамилия-э4ф7в
@ИмяФамилия-э4ф7в 3 жыл бұрын
Вот это я тоже хотел отметить. Вообще, так можно отличить того, кто пользуется 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в спс, было полезно
@mmospanenko
@mmospanenko 3 жыл бұрын
Давай больше подобного, не всегда приходится сталкиваться с подобными фишками а без контекста это не так воспринимается с доки - лайк/подписка)
@SergioUkrAr
@SergioUkrAr 3 жыл бұрын
Супер, контент на высшем уровне, спасибо).
@AbraKadabra000
@AbraKadabra000 3 жыл бұрын
3:31 жесть нечитабельная. Какой-то недо'хтмл. А главное уде на этом этапе хочется начать поиск альтернативных, простых решений
@ЮрийМусатов-ь3я
@ЮрийМусатов-ь3я 3 жыл бұрын
тоже об этом подумал
@Howtogoit
@Howtogoit 3 жыл бұрын
Ты прав( Я нашёл очень плохой пример, потому что тут достаточно было сделать просто type NonAnonymousBook = Required. Не знаю как я не досмотрел такой косяк. Но в целом идея комбинировать утилиты правильная (просто не в этом случае, а если б нужно было слить тип с другим типом например) и конечно тогда вопрос читабильности встанет. Как вариант можно разбить тип на несколько подтипов. ____________________________ Воот красивый пример! Допустим вам нужно сделать интерфейс неанонимных книг о машинах, тогда вот какая может быть комбинация: type CarBook = Required & Omit Ну и если с нагромождением утилит падает читабельность, то можно разбить на несколько типов type NonAnonymousBook = Required type CarModel = Omit type CarBook = NonAnonymousBook & CarModel Вот такие задачи, когда нужно связать какие-то части двух типов между собой и как-то их изменить, гораздо более распространены
@AbraKadabra000
@AbraKadabra000 3 жыл бұрын
@@Howtogoit О! Спасибо, полезно!
@Howtogoit
@Howtogoit 3 жыл бұрын
Воот-с codesandbox.io/s/silly-ritchie-bppkg?file=/src/index.ts Прошу прощения за косячище =)
@TimurShemsedinov
@TimurShemsedinov 3 жыл бұрын
@@Howtogoit Самое плохое в этом подходе, что типы создаются присвоением и выражениями, пошагово, императивно, процедурно, а не декларативно, как в схемах
@danmax8513
@danmax8513 3 жыл бұрын
Требую ещё контента по TypeScript ;)
@max_mgtow
@max_mgtow 3 жыл бұрын
Приветствую бро 🤝👍 Всё очень круто) Всегда жду роликов
@arsenymedoev5562
@arsenymedoev5562 3 жыл бұрын
Хотел увидеть фатальные ошибки TypeScript, а увидел фатальные ошибки разработчиков
@profesor08
@profesor08 3 жыл бұрын
0:50 - 4:00 перезалей, такое говнище нельзя показывать. 4:00 - 5:10 если есть класс, то прекрасно. Но если надо указать какие-то пропсы, то приписка будет либо в начале, либо в конце, либо у интерфейса, либо у функции. Так что эта I это вынужденная мера, чтоб связать визуально две сущности. И пришло это не из .net 7:26 - 7:58 все плохо. Перегрузка нужна для того, чтоб контролировать результат работы функции в зависимости от переданных в нее аргументов. Либо чтоб контролировать передаваемые в нее аргументы и их типы, когда тип последующего аргумента зависит от предыдущего. Если тебе функция ничего не возвращает и не надо контролировать варианты передаваемых аргументов, то перегружать нет смысла.
@MrWerwoolf
@MrWerwoolf 3 жыл бұрын
Лайкнул, подписался, не первое видео смотрю у вас.
@AOne1999
@AOne1999 3 жыл бұрын
Зашел чисто лайк поставить за труд. Потом посмотрю)
@yurakhomitskyi8762
@yurakhomitskyi8762 3 жыл бұрын
Утилиты норм когда у тебя маленькие интерфейсы, но иногда надо 10 ключей взять, и несколько убрать. И эти вложенные утилиты читать сложно. Думаю лучше делать базовые интерфейсы и наследоватся
@yurakhomitskyi8762
@yurakhomitskyi8762 3 жыл бұрын
Или разбить на мелкие и потом мержить Interface1 & Interface2
@BOCbMOU
@BOCbMOU 3 жыл бұрын
Если тебе необходимо пикнуть аж 10 ключей, то логичнее вынести эти 10 ключей в отдельный интерфейс и унаследовать старый интерфейс от нового. К тому же это в целом уникальная ситуация, когда тебе надо аж 10 ключей пикнуть, подобное на практике я видел всего 1 раз в библиотечном типе. Выглядело ужасно и непонятно зачем, то явный пример говнокода на тс.
@yurakhomitskyi8762
@yurakhomitskyi8762 3 жыл бұрын
@@BOCbMOU да хз говно код ли. Бекенд просто странный. У него на разные ендоинты одни и те же модельки имеют разбежности в названиях ключах. И приходилось пикать что-то, выносить в базовые, и короче дубликаты были
@BOCbMOU
@BOCbMOU 3 жыл бұрын
@@yurakhomitskyi8762 так это как раз демонстрация того, что проблема в людях, а не инструментах.) Если фронт/бек/оба не смогли в нормальную типизацию, то тут уже какой язык не бери всё будет плохо.)
@max_mgtow
@max_mgtow 3 жыл бұрын
По поводу префиксов просто убил 😆
@kirills4631
@kirills4631 3 жыл бұрын
2:20 я бы здесь использовал композицию для интерфейса книги вместо утилити типов для статьи, мне кажется такой подход позволяет лучше проработать интерфейсы бизнес сущностей, повышает читаемость и упрощает расширение
@tanercoder1915
@tanercoder1915 2 жыл бұрын
пожалуйста еще такого же контента и много сразу!
@EasyITChannel
@EasyITChannel Жыл бұрын
Инструкция как максимально осложнить жизнь новым разрабам после ухода автора кода. Ну или как сделать себя незаменимым на проекте :) Все сказанное интересно в общеобразовательных целях или как челлендж, но на крупном реальном проекте лучше все делать очевидно и чем проще тем лучше. Чтобы для чтения кода не нужно было сидеть в обнимку со справочником по языку. В любом языке много интересных конструкций, которыми вовсе не обязательно пользоваться. Для очевидности кода лучше сделать два интерфейса отличающихся одним полем, чем использовать что-то экзотическое.
@agnia.starovoitova
@agnia.starovoitova 3 жыл бұрын
Полезное видео, спасибо Единственное, не раскрыта на мой взляд тема, почему плохо мутировать структуры) Потому что очень важно целостное понимание, почему плохо и к чему это может привести. Будет баг - очень размытая формулировка
@mikhailkh8560
@mikhailkh8560 3 жыл бұрын
Так себе видео на самом деле. Что наследование интерфеймов - ну такое, что про префиксы, они наоборот делают проект более читаемым, сразу понимаешь что сюда ты можешь подставить несколлько реализаций. Про мутации - самый яркий пример этой стейт приложения, когда функция не изменяет его а возвращает новый обьект с измененными свойствами. И тогда, если у тебя есть массив этих обьектов то можно посмотреть как изменялись свойства, либо вернуть систему к какому то стейту. Или реализовать функцию отмены ctrl+z. Вообщем есть свои плюсы.
@kai.hexenzorn
@kai.hexenzorn Жыл бұрын
@@mikhailkh8560 Префиксы для интерфейсов - прошлый век, сейчас можно использовать ide, чтобы назначить интерфейсу другой стиль, например, я использую цвет как у класса, но меняю написание интерфейса на курсив. И сразу понятно без всяких префиксов, с чем я имею дело, даже если код написан не мною.
@xela_8746
@xela_8746 3 жыл бұрын
Спасибо за контент...
@edwardfreedom
@edwardfreedom 3 жыл бұрын
..... . ... . . .. . . .. .
@Eugene.g
@Eugene.g 3 жыл бұрын
Сорри, но шо-то ересь какая-то. Pick и пр утилиты с точки зрения читаемости кода - ужас, по-моему они сделаны для того чтобы писать в ФП стиле т.к. в ФП есть and, or типы. Interface существует вообще для другого, это контракт, а не описание типа. Чтобы не повторяться, есть принцип разделения интерфейсов Префикс i ни как не нарушает инкапсуляцию и я не припомню, чтобы хоть раз я переделывал интерфейс в класс По поводу иммутабельности тоже ерунда. Она нужна только если мы пишем в ФП, в ООП мутабильность - благо, просто нужно защищать стейт объекта, например, при помощи геттеров и сеттеров, для этого и нужна инкапсуляция
@funnyenglish4330
@funnyenglish4330 3 жыл бұрын
Ура! Новое видео🎉
@ВикторСмольяков-щ4в
@ВикторСмольяков-щ4в 3 жыл бұрын
Выпуск огонь! А ещё по этой теме есть?
@denpol9956
@denpol9956 3 жыл бұрын
Удобно читать код с префиксами
@Grayt5
@Grayt5 3 жыл бұрын
Спорная проблема. А если у нас в интерфейс Book добавятся свойства(например ISBN), которые нужны только для него, то проходить по всем Omit'ам и везде добавлять ещё одно поле?
@dever4eg
@dever4eg 3 жыл бұрын
5:44 Возвращаемое значение функции будет unknown, хотя мы точно знаем что оно будет таким же как у колбека который мы передали. Выглядит так как будто можно было использовать дженерик и все бы прекрасно типизировалось (дженерик прописывать явно при вызове не нужно, он сам распознает исходя из переданного колбека)
@Glotka
@Glotka 3 жыл бұрын
А потом эти утилитарные типы превращаются в 3х строчных малочитабельных монстров, где тронь одно и повалится все как в начале видео. Расширить или как то поправить базовые типы будет проблематично т.к. все правки придется вносить и в те же утилиты Pick и Omit, где они не нужны или наоборот нужны. Мое имхо что это все конечно прекрасно, но лучше пусть у меня будет 100500 похожих раздельных типов чем каша из 3-4 статичных типов и утилит.
@alexperemey6046
@alexperemey6046 Жыл бұрын
Если у тебя все типы объявлены в одном месте, то не такая уж и каша. Тем более постоянно выводить их не нужно, тебе ж редактор показывает, что в типе. Но да, сильно усложнять, чтобы прямо длинная цепочка утилит была - нечитабельно. Я не знаю, почему автор не упомянул классический вариант - расширение одного интерфейса через другой или их композицию.
@snatvb
@snatvb 3 жыл бұрын
Про ImmuableJS ты не правильно понял. Эта библиотека не для закрытия изменений используется, а для дешевой иммутабельности. Какая самая большая проблема иммутабельности? Она дорогая, как по памяти, так и по времени изменения, ведь требует дополнительных аллокаций. Чтобы изменить массив из 10 000 элементов, тебе нужно скопировать 10 000 элементов - O(n) ImmuableJS дает возможность иммутабельно изменять элемент внутри массива за O(1), там используется хитрая система, зачем нам копировать все, если можно изменить объект, сослаться на него и остальные просто переложить? если у нас программа не изменяемая, то все будет ок, этот принцип работает в языке Closure, на ее принципах и построена эта библиотека
@Max-nr1bv
@Max-nr1bv 3 жыл бұрын
Проблема с большим количеством одинаковых типов должна решаться архитектурой приложения, а не утилити типами. Если в проекте большое количество одинаковых типов, это повод задуматься, а что идёт не так. Решая проблему архитектуры сложными типами мы повышаем сложность программы, ее связанность, а главное не решаем корень проблемы
@awenn2015
@awenn2015 2 жыл бұрын
Поддерживаю, там явно в проекте кто за ним стоит не с того начал
@a1ex_sk
@a1ex_sk 3 жыл бұрын
Типы и интерфейсы это и технически разные сущности, и главное они разные семантически. Если на проекте используется DI (слабо себе представляю, как на крупном проекте поддерживать качество кодеда без DI), или по любым другим причинам имплементация сервисов отделяется от декларации, то префикс "I", как минимум улучшает читаемость. В любом случае, все зависит от конкретного проекта, принятых стайл-гайдов и прочего, и однозначно заявлять, что префиксы - зло...ну такое
@romanaleksandrovich8219
@romanaleksandrovich8219 3 жыл бұрын
а я префикс "I" в имени интерфейса скорее считаю анти-паттерном. Зачем мне знать является ли тип с которым я работаю "абстрактным", контракт которого кто-то реализовал, или я уже напрямую работаю с реальным типом(например классом). Клиентскому коду должно быть в принципе все равно, потребляет ли он интерфейс или класс. Liskov Substitution Principle вот он где. А если в вашем коде вы прямо на уровне нейминга разделяете эти понятия, то вы сразу создаете abstraction leak. Единственное исключение из правил это рефлексия. Если вы активно используете ее в вашем коде, тогда я вижу смысл в разделении реальных и "абстрактных" типов, потому что сама логика вашего кода на этом построена.
@a1ex_sk
@a1ex_sk 3 жыл бұрын
@@romanaleksandrovich8219 зависимости должны быть от абстракции. Естественно, в реальности все зависит от проекта, используемого стека и конкретной задачи, но в общем случае, зависимость от реализации - это плохо и, например, на том же код-ревью должно привлечь внимание. Опять таки, это не какое-то жесткое правило. Есть плюсы и минусы. Если вам на конкретном проекте нужна семантика интерфейсов, с учётом особенностей вашего DI (если вы вообще его используете), используйте. Не нужна - конечно нет смысла коллег вводить в заблуждение и усложнять жизнь
@voliansky
@voliansky 3 жыл бұрын
Абсолютно не согласен с использованием утилитных типов. Если типы отличаются семантически, то просто необходимо создавать два отдельных типа, даже если на на данный момент все поля одинаковые. Такие типы могут потенциально развиваться отдельно друг от друга и могут сильно отличаться после нескольких релизов. Не стоит плодить ненужные зависимости, когда лень создавать новые типы из-за совпадения полей.
@slavagermonenko2206
@slavagermonenko2206 3 жыл бұрын
Простейший пример использование утилиты Omit Например, есть сущность. (например User), у которой много разных полей. Когда мы получаем с бэка список этих сущностей в сервисе и далее передаём их в компоненты/резолверы используем тип User. Однако если нам необходимо написать сервис, который добавлял бы нового юзера. В таком случае нам не нужны поля типо Id, или ещё какие-нибудь служебные поля, которые сами генерятся. В таком случаем аргументом функции добавление юзеров можно сделать что-то типо Omit
@RainbowJet1
@RainbowJet1 3 жыл бұрын
Круто, спасибо)
@akatsukinoyami
@akatsukinoyami Жыл бұрын
Второй пример в первой секции (там где Required + Omit), разве не проще сделать так? interface NewInterface extends OldInterface { author: string; } Это и сохранит старые поля, и сделает нужное поле обязательным, но выглядит проще и читабильнее.
@Max-nr1bv
@Max-nr1bv 3 жыл бұрын
Правило: "никогда не дублируй ...типы" неверно. Даже правило: "никогда не дублируй код" неверно. Вообще слово никогда в программировании нет смысла употреблять в принципе. Плюсы дублирования кода: Меньшее зацепление, легче поддерживать, если сущности изначально разные. Бездумное следование принципу DRY приводит к сложнейшим кускам кода с кучей флагов и условных выражений. Минусы дублирования и так все знают. Я не говорю, что дублировать код нужно всегда, но нужно думать и взвешивать все за и против перед принятием решения
@thekingportalgames8599
@thekingportalgames8599 Жыл бұрын
interface Article extends Book ?
@blacksword3083
@blacksword3083 3 жыл бұрын
Почему в примере с executeValidators не дать TS самому за`infer`ить тип?)
@QwDragon
@QwDragon 2 жыл бұрын
В закреплённом комментарии все ссылки битые... Можно поправить? Особенно codesandbox интересует. Пытался написать под ним, но там моё сообщение видно только мне, так что напишу отдельно ещё раз. А что касается утилитарных типов, то они классные и очень полезны, но стоит посмотреть, как они пишутся и научиться такие же писать самому. Наматывание нескольких типов один поверх другого потенциально опасно, а если ты можешь сам записать в один маппинг (впрочем, в примере с Required это невозможно), то это может помочь. Лично сталкивался с такими проблемами при наматывании типов (и приходилось переписывать): - TS может проверить тип, но не может подсказать: никакого автокомплита и предложений от ide, только постфактум подсветка, накосячил ты или нет. - При совмещении с generic'ом невозможность вывести тип generic'а и скатывание в фоллбэк или unknown, хотя при явном указании всё проверяется корректно. - Невозможность синхронизации типов ключей в сочетании с keyof: по схеме формирования типов два типа имеют одинаковые ключи, но тайпскрипт этого не понимает и отказывается разрешать ключи одного типа для обращения к другому.
@keipa-code6112
@keipa-code6112 3 жыл бұрын
Использование утилит лучшая практика, чем создавать тип-наследник и в него добавить нужное свойство?
@ИмяФамилия-э4ф7в
@ИмяФамилия-э4ф7в 3 жыл бұрын
Тип-наследник? Это как?
@darwim
@darwim 3 жыл бұрын
Топчик)
@ivanpavlovschi7092
@ivanpavlovschi7092 3 жыл бұрын
Большинство девелоперов использующих префиксы просто выпендриваются намекая на то, что они пришли в мир TS из Java/C#... А все разговоры типа это улучшает читабельность просто отмазки.. Остальная же часть девелоперов использующих префиксы, увидели/услышали где-то что так надо. Автор молодец.
@PvlIv
@PvlIv 3 жыл бұрын
В джаве никогда не писали префиксы для интерфейсов (было для переменных), в обоих языках любые префиксы давно муветон
@m.kozylov
@m.kozylov 3 жыл бұрын
Как в первую очередь C# разработчик вот эти утилиты выглядят как какой то костыль, есть же Interface segregation, наследоваие в TS поддерживается, так сделать общий интерфейс IPageCount(свойство pagesCount), и его наследовать для Book\Article. За префикс 'I' для интерфейсов то смысл тут к и в C#, интерфейс это контракт что должно быть в типе(ок, в JS\TS его не обязательно реализовывать) а класс имеет некую реализацию, значение свойств по умолчанию и тп., как бы концептуально смысл разделять эти вещи есть(да и инициализируются они по-разному), но для веб не кажется таким уж критичным. Разве переименовать тип в IDE является какой то проблемой, есть же функции для рефакторинга.
@nefertisu6818
@nefertisu6818 3 жыл бұрын
Про префикс I абсолютно не согласен, так мы явно видим что ожидаем увидеть ИМЕННО интерфейс или кого-то кто его имплиментирует, это не нарушает инкапсуляцию абсолютно да и слово инкапсуляция здесь абсолютно неприменимо, тут ты скорее хотел затронуть абстракцию
@BOCbMOU
@BOCbMOU 3 жыл бұрын
А как отличить интерфес от не интерфейса? type SomeType = ISomeType1 | ISomeType2 - это всё ещё интерфейс или уже нет? type SomeType = { a: number } - это уже интерфейс или нет? interface SomeFunc { (): void } - а это интерфейс или нет? Если его использовать всегда, то зачем он нужен? А если опционально, то удачи выставить границы. Я как-то пытался и в итоге понял, что это не имеет никакого смысла, читабельность это не повышает, а геморрой создаёт. Всё равно подавляющее большинство типов это интерфейсы объектов, а те же функции итак видны по названию. А ещё я не припомню ни один актуальный пекедж с типами, в котором используется I. Может и есть, моя выборка невелика, всё же пакетов как грязи, но не думаю, что найдутся такие из популярных.
@a4y_m5r
@a4y_m5r 3 жыл бұрын
Дядь, это не .net и не Java. Какие ещё префиксы I?
@Mark1-f2n
@Mark1-f2n 3 жыл бұрын
Жду классных примеров с дженериками
@АлексейБомко-ь1ш
@АлексейБомко-ь1ш 3 жыл бұрын
Так! СНАЧАЛА СТАВИМ ЛАЙК, А ПОТОМ СМОТРИМ :)
@alexperemey6046
@alexperemey6046 Жыл бұрын
А я вот пишу I в начале. Но я их пишу и для классов тоже. Потому что "интерфейс" - это понятие логическое. Класс - тоже является интерфейсом. Но у меня классы с I выполняют роль интерфейсов, т.е. они внутри кроме полей и конструктора (и еще возможно геттеров-сеттеров) ничего не содержат.
@TimurShemsedinov
@TimurShemsedinov 3 жыл бұрын
строгая типизация в рамках системы типов js, это как связать руки тому, у кого уже ноги переломаны
@TimurShemsedinov
@TimurShemsedinov 3 жыл бұрын
1. Не любая конструкция джаваскрипт может быть типизирована тайпскриптом, а то, что это надмножество - это просто маркетинговое вранье. 2. Иногда он неправильно обрабатывает типы и находит ошибки там, где их нет, а пропускает там, где они есть. 3. Основные ошибки они не в системе типов, а в логике программы, в неправильной декомпозиции, в анипаттернах, которые можно без труда покрыть типами и проблема не решится. Разработчики находятся под гипнозом ложной надежности и они меньше заботятся о тестах и ревью кода. 4. В рантайме проверки типов нет, а при взаимодействии клиента и сервера или микросервисов друг с другом все проверки нужно делать руками. 5. Разработчики бегут от сложности предметной области в уютный мирок обсуждения типов в курилках, это достаточно круто звучит все и делает видимость сложного и серьезного дела, чтоб не концентрироваться на душных задачах бизнеса. 6. В нем нет автовывода, а вместо него все много раз дублируется и захламляет код, снижая его читаемость и понятность. 7. Тайпскрипт некоторые идеи передаст в js и отомрет, тогда нужно будет переписывать проекты, как уже было с кофескриптом и многими другим суррогатными языками. 8. Нет четкой спецификации синтаксиса языка, она вообще отсутствует и язык состоит из отдельных фич, которые можно включить и выключить в конфиге. 9. Тестирование решает те же проблемы, но делает это надежнее, потому, что проверяет не только сигнатуры, но и сложное поведение, в том числе асинхронное. 10. Ну и как показал уже Илья в докладах - это экономически не выгодно. Деньги потраченные на юниттесты дают лучший результат.
@СергейЛавров-б9й
@СергейЛавров-б9й 3 жыл бұрын
А что вы предлагаете делать вместо TS?
@ApelsinovIvan
@ApelsinovIvan 3 жыл бұрын
За то TypeScript позволяет делать оверинженеринг, списывать любое ко-во часов, которое мне не давали списывать на тесты, и чувствовать себя грамотным перцем среди лошков
@СергейЛавров-б9й
@СергейЛавров-б9й 3 жыл бұрын
Ты знаешь правило: критикуешь - предлагай
@rudenkom
@rudenkom 3 жыл бұрын
@@TimurShemsedinov поддерживаю
@Nikitosss91
@Nikitosss91 3 жыл бұрын
Чел, сделай курс по ТС , а может и по реакту с редаксом, объясняешь как боженька
@kai.hexenzorn
@kai.hexenzorn Жыл бұрын
Во всех нормальных ооп-языках совсем не случайно присутствует именного перегрузка методов или использование интерфейсов в качестве параметров, а не union-типы. Union-типы почти тоже самое что и any, все они убивают полиморфизм, без которого код не может быть чистым. Особенно "радует" часто используемые типы вроде: string | undefined. А это разве не дублирует логику опционалов? Почему не использовать "const value: string?" тогда. Опциональные цепочки работают на чтение, но почему-то не работают на запись. Стирание типов - это то ещё минное поле. Не ооп, а китайская подделка...
@bubblesort6368
@bubblesort6368 3 жыл бұрын
Проблема все этих утилитных типов и всяческих комбинаций с ними в том, что в последствии черт ногу сломит какую структуру они имеют в итоге. Так как эта структура размазана и перемазана не несколько файлов с иероглифами и тернаринками в них. И как-то ведь живут люди в других яп без этого? В Go, Rust такого нет и люди не жалуются...
@TheProfessionalGambler
@TheProfessionalGambler 3 жыл бұрын
Еще и ошибся в методе интерфейса Cat: *eat(food: Food): Poop*
@hulumulu1108
@hulumulu1108 3 жыл бұрын
Больше TS пжлста
@code-pro
@code-pro Жыл бұрын
Про Pick, Omit - бред, на реальном проекте так нельзя делать, ничего плохого нет в дублировании некоторых полей для разных, не связанных сущностей. Не забывай, что помимо того, что сущности расширяются, иногда поля могут и убираться
@Банки
@Банки Жыл бұрын
Не понравилось про обязательное наследование по причине схожести полей. Вредный совет.
@TheJabberwahh
@TheJabberwahh Жыл бұрын
Всмысле?? Ты просто хотел Нон анонимус бук с обязательным автором? Тогда просто Реквайред на Буке. А ты и пик и омит сгородил. Типичные фронтендеры....
@СергейТимушев-н8й
@СергейТимушев-н8й 3 жыл бұрын
сколько можно толкать эту имутабельность?) ну это же бред) весь mobx строиться на мутабельности данных. и работает быстрее имутабельного редакса) быстрее и дешевле в плане процессорного времени и объема памяти)
@cijic
@cijic Жыл бұрын
И этот бред выдаётся за хороший код? Изучите рефакторинг и не страдайте всяким.
@СергейПресняков-о4р
@СергейПресняков-о4р 3 жыл бұрын
Я не учу TypeScript. Зачем я это смотрю?
@dotvkab
@dotvkab Жыл бұрын
Автор хуже джуна, почитать про умные вещи почитал, а понять их забыл
@stasostrin47
@stasostrin47 Жыл бұрын
Первые четыре минуты про типы и мапинг какая то хрень... Неужели нельзя сделать базовую абстракцию, а от нее уже клепать книги и неанонимные книги.... Мапинг вообще ужасно плохо читабельная вещь
@diogen8443
@diogen8443 Жыл бұрын
Субьективщина.
@zeropoint6130
@zeropoint6130 2 жыл бұрын
Просто пишете на JavaScript и не паритесь :D
@sergeys452
@sergeys452 3 жыл бұрын
Какой ужас, вот насмотрятся джуны таких видосов и плачь потом над мерж реквестом. Да и незнающие будут ругать потом тс. Для незнающих ТС: В ТС ничего страшного нет! Его прям максимально приблизили к норм ООП языкам. И как и везде, его можно использовать как попало, а можно красиво и читабельно: interface IArticle { price: number; author?: string; } interface IBook extends IArticle { pagesCount: number; } И всё. Не нужно тут никакие омиты
@ArtemyKairyak
@ArtemyKairyak 3 жыл бұрын
в твоем примере не учтено, что свойство автор в статье должно быть обязательным
@sergeys452
@sergeys452 3 жыл бұрын
@@ArtemyKairyak так в видео автор необязателен в обеих структурах. См. 1:19
JavaScript - проповедь Чистого кода!
15:09
Как пройти в IT?
Рет қаралды 47 М.
Чудовищно функциональный JavaScript
21:31
Как пройти в IT?
Рет қаралды 55 М.
TypeScript - секретные материалы!
13:19
Как пройти в IT?
Рет қаралды 31 М.
Самые частые ошибки в TypeScript
9:41
PurpleSchool | Anton Larichev
Рет қаралды 17 М.
TypeScript теперь в CSS?! Это как?
9:12
Как пройти в IT?
Рет қаралды 12 М.
Frontend заменит мобильную разработку? WTF?!?!
11:15
Как пройти в IT?
Рет қаралды 11 М.
Styled-component + TypeScript урок. Частые проблемы и ошибки
7:57
Полина про Frontend 💜
Рет қаралды 3 М.
Как пишут код для Космоса?
13:07
Как пройти в IT?
Рет қаралды 6 М.
Docker Для Начинающих за 1 Час | Docker с Нуля
52:43