Привет! Это моя первая статья на Хабре и в ней я хочу рассказать про такой язык, как TypeScript, и почему именно на нем вместо Javascript ты должен начать писать уже в этом году! В данной статье приведу 2 примера, когда TypeScript поможет нам избежать ошибки или подскажет, что что-то не так. Погнали!

1. Стандартная типизация входящих аргументов функции и возвращаемого значения

Приведу 2 простых примера :

function sum (a,b) {
  return a + b;
}

console.log(sum(1,2)); // Вернет 3
function concatenation (a,b) {
  return a + b;
}

console.log(sum("Let's ","start!")); // Вернет "Let's'start!"

Пока что все в порядке. Но если аргументы в функции sum поменяются на string тип а в функции concatenation на number, то и тип возвращаемого результата и сам результат поменяются, и будут некорректными

function sum (a,b) {
  return a + b;
}

console.log(sum('Start',2)); 
// Вернет уже не сумму а результат сложения строки с числом "Start2"
function concatenation (a,b) {
  return a + b;
}

console.log(sum(1,2)); // Вернет 3

Но если мы напишем те же функции с использованием Typescript и опишем их типами, то отловим данные ошибки на этапе компиляции

function sum (a: number,b:number):number {
  return a + b;
}

console.log(sum('Start',2)); 

Наша IDE подсветит нам, что данная функция принимает тип number, а не тип string, и компиляция не пройдет

Argument of type 'string' is not assignable to parameter of type 'number'.ts(2345)

Также и в примере с функцией concatenation

function concatenation (a:string,b:string):string {
  return a + b;
}

console.log(sum(1,2)); 

Argument of type 'number' is not assignable to parameter of type 'string'.ts(2345)

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

2. Typescript может эффективно подсказывать в IDE

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

function getValueFromObj(obj, key) {
	return obj[key];
}

const Obj = {
	'a': 1
}

console.log(getValueFromObj(Obj, 'a')); //Вернет 1

Но что будет, если передать в аргумент ключ, которого нет в объекте? Обычный Javascript пропустит эту ошибку. Но мы можем превентивно описать типы так, чтобы если мы уже знаем, что за объект у нас будет и какие у него ключи, мы не пропустим ключ, которого нет в объекте!

function getValueFromObj<T, K extends keyof T>(obj:T, key:K) {
	return obj[key];
}

const Obj = {
	'a': 1
}

console.log(getValueFromObj(Obj, 'b'));

Данный код не скомпилится, и Typescript подчеркнет нам второй аргумент функции с напоминанием, что такого ключа нет в объекте!

Argument of type '"b"' is not assignable to parameter of type '"a"'.ts(2345)

Стоит отметить, что данная проверка является лишь помощью в нахождении ошибок подобного рода и Typescript'a лишь проверяет на ошибки и скомпилится в нативный JS, в рантайме же нет Typescript'a и он не поймает там эту ошибку!

Кроме данных фичей, какие еще преимущества?

В настоящее время всё больше компаний начинают свои проекты на Typescript или переписывают свои старые проекты. Это обусловлено тем, что Typescript уже де-факто стандарт в написании проектов.

Я приведу список преимуществ:

  • С каждым годом популярность Typescript только растёт! В доказательство этого приведу ссылку из последнего developer survey

  • Отличная поддержка типов библиотеками

  • Легко внедряется: поскольку Typescript совместим с Javascript, проект можно постепенно переводить на Typescript!

  • Лёгкий старт: Сравнительно легкий старт для начала. Можно начать с гайда Typescript за 5 минут и уже успешно практиковаться!

Выводы

  • Вы не должны писать каждый проект на Typescript, но если вы пишите библиотеку, то Typescript лучший выбор, так как возможно её будут использовать в проектах с Typescript.

  • Typescript не поможет вам найти все ошибки в вашем проекте, но он поможет вам писать красивый типизированный код!

Комментарии (10)


  1. GebekovAS
    22.05.2022 15:12
    +5

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

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

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


  1. sanchezzzhak
    22.05.2022 18:50
    +6

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


    1. platonlukyanov2007
      22.05.2022 20:16
      -4

      Ознакомьтесь, пожалуйста, со второй причиной


    1. bromzh
      22.05.2022 22:49

      Допустим, в проекте есть 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? Есть ли гарантии, что мы отрефакторили все места правильно?


  1. coder_one
    22.05.2022 19:08
    +2

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


  1. ZoomLS
    22.05.2022 19:24
    +4

    >Typescript уже де-факто стандарт в написании проектов.

    Очень спорное заявление.


  1. HemulGM
    23.05.2022 00:42
    +3

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

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


    1. baklajan
      23.05.2022 08:56

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


  1. PunkMachine
    23.05.2022 10:28
    +1

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

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

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


  1. MaxKyselov
    25.05.2022 08:51

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

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

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

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

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

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

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