Pull to refresh

Comments 15

В примерах и описании ошибки и опечатки. Объявляется функция concatenation, но в обоих примерах вызываешь sum.

поменять... тип а в функции concatenation на number, то и тип возвращаемого результата и сам результат поменяются,

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

Почему всём и почему, я должен? мне вот совершено не нужен ts, мне хватает тестов и doc type.

Допустим, в проекте есть 2 структурно идентичных объекта с полями id и name (вот так совпало). Но хотя они и идентичны структурно, они олицетворяют разные доменные модели. Эти объекты очень обильно используются в проекте, пусть каждое из полей используется в 100 разных местах. Эти объекты получаем как с бэкенда, так и создаём на фронте.


Теперь нам надо в одном из объектов изменить имя поля name -> code. Как это сделать просто без тайпскрипта?


На ts в коде каждому объекту будет соответствовать интерфейс:


interface Item {
  id: string;
  name: string; // это поле надо переименовать в code
}
interface User {
  id: string;
  name: string;
}

Соответственно, всякие функции, которым по логике нужен User в аннотации типов и будет User, где нужен Item будет Item:


function getUser(): Promise<User> {}
function addItem(item: Item): void {}
function getUserItems(user: User): Item[] {}

И проблема рефакторинга решается за минуту: просто переименовываем через IDE поле в интерфейсе Item, и все использования name, относящиеся к Item автоматом переименуются. Без IDE рефакторить хоть и дольше, но всё ещё надёжно — typescript просто не соберёт проект, если где-то, где используется Item будет старое имя поля.


Как эту проблему просто решить в чистом js с тестами и jsdoc? Есть ли гарантии, что мы отрефакторили все места правильно?

"и почему именно на нем вместо Javascript ты должен начать писать уже в этом году!". Никого не хочу обидеть, но никто и никому не должен. Каждый выбирает свой язык программирования. Везде есть свои особенности: плюсы и минусы.

И в чем же в первом примере "не корректно"? Если ты передаешь строку и число для суммирования ты понимаешь, что будет в результате, разве не так?

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

Так на том же TypeScript можно писать и без типов. TypeScript предоставляет выбор: хочешь безопасно и с защитой от дурака - пиши строго типизированно, хочешь быстро и не безопасно - пиши как на JavaScript.
Чистый JavaScript не предоставляет выбора.

У меня никогда не было багов с типами данных в JS, просто потому что я всегда знаю, что мне приходит с backend и, как я должен это обрабатывать у себя. Я в коммерческой разработке хоть и меньше года, но думаю, если бы TS был критически нужен - я бы уже это заметил.

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

Поправьте, если не прав. Буду рад поговорить на эту тему с более опытными людьми.

  • Типы — это контракты, договорённости о согласованности кода. Активная самообновляемая документация. Меняется контракт — программа становится некорректной до тех пор, пока всё что затрагивает контракт не изменится в соответствии с ним


  • Типы позволяют раньше выявлять некоторые ошибки и избегать всяких простых глупостей, связанных с динамической типизацией. Например, банальные опечатки. Или что-то типа такого:


    type Item { id: string; code: string }
    function getItem(id: string): Item {/* тут какая-то логика */}
    const itemCode = getItem('1').сode; // тут ошибка. заметно?

    На деле, в ошибочной строчке с в слове code — кириллическая. Удачи с отловом этого в js.


  • Типы позволяют сделать неправильное состояние с точки зрения бизнес-логики невыразимым в программе


  • Типы могут отслеживать полноту и корректность паттерн-матчинга. В JS конечно такой себе паттерн-матчинг, и это пример не совсем про него, но всё же:



enum Color {
  RED = 'red',
  GREEN = 'green',
  BLUE = 'blue',
}
const ColorMap: Record<Color, string> = {
  [Color.RED]: '#f66666',
  [Color.GREEN]: '#75bb52',
  [Color.BLUE]: '#112233',
}

Если мы добавляем или удаляем цвет в енуме, но забудем сделать это в словаре — ошибка сборки. В JS отловим только в рантайме.


Енум компилится в такой объект

var Color;
(function (Color) {
Color["RED"] = "red";
Color["GREEN"] = "green";
Color["BLUE"] = "blue";
})(Color || (Color = {}));


Это что пришло первое в голову. Плюсов конечно же больше, минусов почти нет. Всем советую.

Спасибо за расширенный ответ!

В реальном приложении в функцию передаю переменные, которые приходят с бека или пользовательского ввода. Как решить вопрос синхронизации ответов бека и ваших TS интерфейсов?

Добавьте реальные минусы использования TS кроме плюсов в статью чтобы разработчик мог взвесить:

  • TS занимает не большую долю рынка (5-7% от всего js кода если не ошибаюсь)

  • Повышает порог вхождения в проект

  • Делает юнит тесты более трудоемкими

  • Делает написание сложных структур трудоемкими

Считаю целесообразным использование TS в пакетах компонентов (т.е. мы точно знаем какой тип будет у пользовательского ввода), фреймворков и т.д.

Как решить вопрос синхронизации ответов бека и ваших TS интерфейсов?

Описывать контракты того, чем обмениваетесь (для этого можно взять protobuf/openapi/messagepack/etc) и генерировать клиенты/контроллеры на бэке и фронте.

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

Начинать писать на этом надо было несколько лет назад

Sign up to leave a comment.

Articles