fullstack-development / react-redux-starter-kit

Modular starter kit for React+Redux+React Router projects.
https://demo.fullstack-development.com/
MIT License
91 stars 13 forks source link

Отказаться от интерфейсов? #150

Open chmnkh opened 4 years ago

chmnkh commented 4 years ago

ишью Сереги мне напомнили одну мысль, которую я вынашиваю

мы сейчас используем типы и интерфейсы, притом использование интерфейсов особо ничем не обосновано, мы не пишем интерфейс-интерфейс, а описываем просто тип чего-то, и в 95% случаев, когда мы их используем, они запросто заменяются типом без потери смысла/функционала

в то же время это кучу запутанного и всратого кода создает, типа type IProps = .... сфига-ли там префикс I, во-первых, и почему остальные пропсы написаны интерфейсами, а этот - типами (пс: потому что extends Interface {} выглядит убого)

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

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

опять же надо подумать как их писать: добавлять ли префикс T и прочее

дискасс

sk1e commented 4 years ago

интерфейс это связка имени и типа, а тип - просто тип. Без интерфейсов у тебя ошибки компилятора превратятся в огромные нечитаемые куски текста, т.к. там где были просто имена интерфейсов будет полное описание типа

in19farkt commented 4 years ago

Серег, кажется это не так)

вот на типе: image

вот на интерфейсе: image

Текст ошибки идентичен

chmnkh commented 4 years ago

я тоже не понял о чем Серега, можно пруфы?

sk1e commented 4 years ago

я про это https://www.typescriptlang.org/docs/handbook/advanced-types.html#interfaces-vs-type-aliases сам не проверял. Просто помню что читал про это. Попозже проверю

chmnkh commented 4 years ago

ну тут надо подумать/поизучать, но я оставил, чтобы это не забылось

in19farkt commented 4 years ago

по мне так можно оставить как есть (юзать interface где это возможно, для остального type), но отказаться от правила помечать префиксом I типы объявленные с помощью interface. Возможно ввести критерии, по которым можно понять какие именно интерфейсы и алиасы нужно таким префиксом помечать.

Znack commented 4 years ago

Я в целом за то, чтобы убрать префиксы — ни I, ни T на самом деле не нужны. Сейчас уже почти полгода на проекте без префиксов — ни разу не чувствовал их необходимость :)

sk1e commented 4 years ago

Я за то, чтобы оставить всё как есть и категорически против того что бы префикс убирать. Префикс помогает визуально отличать объекты от необъектов, это полезно.

А правило простое: префикс I - для типов которые объявлены через interface и для пересечения нескольких интерфейсов, для всех остальных - без префикса. Union интерфейсов это не интерфейс и соотвественно тоже не должен иметь префикса

sk1e commented 4 years ago

Сейчас уже почти полгода на проекте без префиксов — ни разу не чувствовал их необходимость :)

на хаскеле?

chmnkh commented 4 years ago

Я за то, чтобы оставить всё как есть

по мне так можно оставить как есть

вопрос: почему плохо/не стоит писать все на типах? пока все что я видел - это мессадж @sk1e про ошибки, но там без пруфов и надо чекать

sk1e commented 4 years ago

Я за то, чтобы оставить всё как есть

по мне так можно оставить как есть

вопрос: почему плохо/не стоит писать все на типах? пока все что я видел - это мессадж @sk1e про ошибки, но там без пруфов и надо чекать

пруфы я привёл, но видимо документация неактуальна

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

Znack commented 4 years ago

на хаскеле?

Не, на TS.

Но на Хаскеле кстати тоже.

Зачем тебе именно по имени определять, что внутри за типом скрыто? Ну когда нужно, провалишься в него по ctrl+клик, тебе все равно придется это делать, если ты хочешь посмотреть что там в объекте

Znack commented 4 years ago

А так получается, что небольшая потребнсть, которая возникает время от времени, заставляет тебя писать по-особенному всё время вообще, со всеми интерфейсами во всех модулях

in19farkt commented 4 years ago

Просто с этим префиксом не всё однозначно. Не понятно где нужно его применять, а где нет, и соответственно правило линтера нихера по сути не линтит, потому что как считает сам же Серега, пересечение двух интерфейсов нужно помечать префиксом I, а линтер в такое не умеет.

Union интерфейсов это не интерфейс и соотвественно тоже не должен иметь префикса

И вот с этим заявление я категорически не согласен.

sk1e commented 4 years ago

на хаскеле?

Не, на TS.

Но на Хаскеле кстати тоже.

Зачем тебе именно по имени определять, что внутри за типом скрыто? Ну когда нужно, провалишься в него по ctrl+клик, тебе все равно придется это делать, если ты хочешь посмотреть что там в объекте

так я могу визуально, без всяких кликов определить. Когда я захочу посмотреть что там внутри это уже другой случай. Иногда удобно просто понять что это объект

sk1e commented 4 years ago

Union интерфейсов это не интерфейс и соотвественно тоже не должен иметь префикса

И вот с этим заявление я категорически не согласен.

Это множество интерфейсов)

in19farkt commented 4 years ago

Это множество интерфейсов)

что в свою очередь тоже является интерфейсом

sk1e commented 4 years ago

Это множество интерфейсов)

что в свою очередь тоже является интерфейсом

но нет же, как и множество чисел не является числом

in19farkt commented 4 years ago

Иногда удобно просто понять что это объект

Не понимаю в чем удобство :)

sk1e commented 4 years ago

Иногда удобно просто понять что это объект

Не понимаю в чем удобство :)

Получаешь больше информации, без всяких кликов и переходов

in19farkt commented 4 years ago

Получаешь больше информации, без всяких кликов и переходов

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

in19farkt commented 4 years ago

но нет же, как и множество чисел не является числом

Почему? в итоге то конечным значением будет число. Не понимаю твою логику :)

in19farkt commented 4 years ago

тут мне кажется в обратную строну должно работать. Типа нельзя сказать, что число это какое-то множество чисел (если мы говорим об ограниченном множестве), а вот любое множество чисел в итоге является числом. Как минимум если мы рассуждаем в разрезе типа и значения какой-то переменной, не углубляясь в философию :)

sk1e commented 4 years ago

но нет же, как и множество чисел не является числом

Почему? в итоге то конечным значением будет число. Не понимаю твою логику :)

Я короче допустил ошибку в рассуждениях. Множество и элемент множества, конечно разные вещи, но union не создаёт множество значений а добавляет в него. Тогда, действительно, тип union'а интерфейсов так же сам есть интерфейс

Znack commented 4 years ago

Надо чётко тогда понимать, как часто тебе

Иногда удобно просто понять что это объект

Потому что ни мне, ни Диме особо потребности и удобства в этом нет :) Я боюсь, что для относительно редкого кейса мы вынуждены менять кодстайл, который аффектит на нас всех еще и 100% времени работы с кодом

sk1e commented 4 years ago

Получаешь больше информации, без всяких кликов и переходов

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

ок, в принципе наверно можно всё же обойтись без префиксов

sk1e commented 4 years ago

тогда действительно можно отказаться от интерфейсов. Но там есть всё же некоторые различия https://github.com/microsoft/TypeScript/pull/7029 https://github.com/microsoft/TypeScript/issues/28174, нужно проанализировать как они могут повлиять

kinda-neat commented 4 years ago

Я поддерживаю @sk1e, не знаю насчет пруфов, но у меня в голове довольно четко разделены объекты через интерфейсы и unions & type aliases, не понимаю зачем это все мешать в одно определение type

Если я вижу IEntity, то я понимаю что это объект, если я вижу Entity, то понимаю что за ним скрыто множество сущностей, типа 'man' | 'woman' | 'car' | 'cat', или допустим я хочу подчеркнуть/сделать более понятным что этот string есть LoaderName

kinda-neat commented 4 years ago

Иногда удобно просто понять что это объект

Не понимаю в чем удобство :)

Получаешь больше информации, без всяких кликов и переходов

поддерживаю, не нужно кликать и переходить внутрь, меньше телодвижений за счет префикса который написан единожды, а работать с интерфейсом я буду кучу раз, либо я один раз помечаю либо постоянно скачу посредством cmd + click

chmnkh commented 4 years ago

у меня в голове довольно четко разделены объекты через интерфейсы и unions & type aliases, не понимаю зачем это все мешать в одно определение type

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

Если я вижу IGender, то я понимаю что это объект, если я вижу Gender, то понимаю что за ним скрыто множество гендеров, типа 'man' | 'woman' | 'car' | 'cat'

во-первых, это просто-напросто не всегда так, (см. выше), во-вторых, это связано с именем всего лишь, т.е. с наличием префикса, в-третьих, в чем от этого профит? конкретно

или допустим я хочу подчеркнуть/сделать более понятным что этот string есть LoaderName

я вообще не понял, причем тут типы и интерфейсы)

sk1e commented 4 years ago

во-первых, это просто-напросто не всегда так, (см. выше), во-вторых, это связано с именем всего лишь, т.е. с наличием префикса, в-третьих, в чем от этого профит? конкретно

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

chmnkh commented 4 years ago

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

почему при именовании переменных, функций и их разных подмножеств, типов, ts классов, scss классов и переменных, мы не пишем никакие префиксы для этого, а здесь вдруг это стало необходимым? и в честь чего это вдруг связано с тем, как именно тип объявлен? даже если бы нам действительно этот префикс нужен бы был (а он не нужен, ящитаю, потому что при именовании переменных, функций и их разных подмножеств, типов, ts классов, scss классов и переменных мы никакие префиксы не пишем и как-то прекрасно живем), это никак не обязано быть связанным с тем, как мы объявляем тип: через интерфейс или через тайп

sk1e commented 4 years ago

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

префикс, кейс, грамматика - какая разница? Это всё разные способы кодирования информации в имя.

и в честь чего это вдруг связано с тем, как именно тип объявлен

это связано косвенно. Префикс показывает не способ объявления типа, а возможное множество его значений. Он не показывает что тип через interface объявлен

in19farkt commented 4 years ago

Скоро все будем юзать префикс # для приватных полей класса и кайфовать от обилия информации зашитой в имя переменных 😂

https://github.com/tc39/proposal-class-fields#private-fields

chmnkh commented 4 years ago

это связано косвенно. Префикс показывает не способ объявления типа, а возможное множество его значений. Он не показывает что тип через interface объявлен

ну так ишью про способ объявления типа, а не про префиксы, просто Макс написал так, как будто если мы добавляем префикс какой-то, например I, то мы должны обязательно этот тип через interface написать, но может я не так его понял

префикс, кейс, грамматика - какая разница? Это всё разные способы кодирования информации в имя.

ну как бы да, факт, но я не понял, как это на мой вопрос отвечает, + это, как я уже выше писал, следующий этап обсуждения - нужны ли префиксы или нет, чтобы до него дойти, надо сначала решить, нужны ли интерфейсы

chmnkh commented 4 years ago

Скоро все будем юзать префикс # для приватных полей класса и кайфовать от обилия информации зашитой в имя переменных

https://github.com/tc39/proposal-class-fields#private-fields

капэц, больше костылей богу костылей

sk1e commented 4 years ago

ну так ишью про способ объявления типа, а не про префиксы

Обсуждали именно префиксы. Твой ишью тут давно уже не обсуждают. Сорян(

chmnkh commented 4 years ago

Обсуждали именно префиксы. Твой ишью тут давно уже не обсуждают. Сорян(

Я поддерживаю @sk1e, не знаю насчет пруфов, но у меня в голове довольно четко разделены объекты через интерфейсы и unions & type aliases

kinda-neat commented 4 years ago

у меня в голове довольно четко разделены объекты через интерфейсы и unions & type aliases, не понимаю зачем это все мешать в одно определение type

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

Насчет этого разделения, откуда оно взялось? откуда ты впринципе какое-то можешь сформировать о используемой технологии? все из документации и конвенциях на уровне языка/технологии, так вот, здесь когда речь идет о шейпе объекта и о контрактах, в доке тайпскрипта используется именно interface, когда речь идет о type aliases используется type Из доки: image Еще есть целый холивар за (не) использование префиксов типа I

chmnkh commented 4 years ago

Because an ideal property of software is being open to extension, you should always use an interface over a type alias if possible.

мне вообще это кажется каким-то приплетением солида не совсем к месту, если честно, во-первых

во-вторых, type ExtendedShape = Shape & {} === interface IExtendedShape extends IShape {}

все из документации и конвенциях на уровне языка/технологии

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

так вот, здесь когда речь идет о шейпе объекта и о контрактах, в доке тайпскрипта используется именно interface, когда речь идет о type aliases используется type

опять же, я не понимаю почему для нас в данном случае ориентир - это дока тайпскрипта (вообще к слову говоря, я лично к доке этой не очень положительно отношусь), а не наше удобство

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

Znack commented 4 years ago

Как это всё напоминает https://en.wikipedia.org/wiki/Hungarian_notation :)

in19farkt commented 4 years ago

Как это всё напоминает https://en.wikipedia.org/wiki/Hungarian_notation :)

Во, нужно завести ишу на эту тему, нужно внедрять, круто же когда в имя переменной вшит ее тип, требую больше информационного шума в коде! 😂

moki commented 4 years ago

рандомно наткнулся на ишью опасения @sk1e

интерфейс это связка имени и типа, а тип - просто тип. Без интерфейсов у тебя ошибки компилятора превратятся в огромные нечитаемые куски текста, т.к. там где были просто имена интерфейсов будет полное описание типа

больше неактуальны начиная с версии ts 2.1 и интерфес и тип алаяс показывают ошибку как

Type NameInterface
Type NameType

к слову можно делать implement [type alias], а extend через type intersection &

kinda-neat commented 4 years ago

Я ща все типы что вижу переписываю на/новые пишу через type, проблем пока никаких не заметил, даже приятнее что не надо эту I добавлять. @sk1e ты можешь попробовать это делать на текущем проекте, потом отпишешься :)

sk1e commented 4 years ago

Я ща все типы что вижу переписываю на/новые пишу через type, проблем пока никаких не заметил, даже приятнее что не надо эту I добавлять. @sk1e ты можешь попробовать это делать на текущем проекте, потом отпишешься :)

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

kinda-neat commented 4 years ago

@Znack, @in19farkt, @chmnkh все, объявляем победу type и фиксируем где-то или как?

kinda-neat commented 4 years ago

задачу делаем чтобы перевести все interface -> type?

chmnkh commented 4 years ago

задачу делаем чтобы перевести все interface -> type?

мне кажется переводить текущий код это так себе задача, можно и обойтись имхо)

@Znack, @in19farkt, @chmnkh все, объявляем победу type и фиксируем где-то или как?

а у нас вроде как нету раздела в ТС со стандартами, мб можно и начать оттуда

Znack commented 4 years ago

задачу делаем чтобы перевести все interface -> type?

Задачу отдельную на эту тему можно сделать, просто приоритет низкий поставить.