Привет! Это моя первая статья на Хабре и в ней я хочу рассказать про такой язык, как 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)
sanchezzzhak
22.05.2022 18:50+6Почему всём и почему, я должен? мне вот совершено не нужен ts, мне хватает тестов и doc type.
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? Есть ли гарантии, что мы отрефакторили все места правильно?
coder_one
22.05.2022 19:08+2"и почему именно на нем вместо Javascript ты должен начать писать уже в этом году!". Никого не хочу обидеть, но никто и никому не должен. Каждый выбирает свой язык программирования. Везде есть свои особенности: плюсы и минусы.
ZoomLS
22.05.2022 19:24+4>Typescript уже де-факто стандарт в написании проектов.
Очень спорное заявление.
HemulGM
23.05.2022 00:42+3И в чем же в первом примере "не корректно"? Если ты передаешь строку и число для суммирования ты понимаешь, что будет в результате, разве не так?
Не везде и не всюду нужна типизация в скриптах. При чем я это говорю как тот, кто пишет в основном на строго типизированном языке.
baklajan
23.05.2022 08:56Так на том же TypeScript можно писать и без типов. TypeScript предоставляет выбор: хочешь безопасно и с защитой от дурака - пиши строго типизированно, хочешь быстро и не безопасно - пиши как на JavaScript.
Чистый JavaScript не предоставляет выбора.
PunkMachine
23.05.2022 10:28+1У меня никогда не было багов с типами данных в JS, просто потому что я всегда знаю, что мне приходит с backend и, как я должен это обрабатывать у себя. Я в коммерческой разработке хоть и меньше года, но думаю, если бы TS был критически нужен - я бы уже это заметил.
TS удобен из-за подсказок для VS Code, TS нужен для библиотек - с этим я полностью соглашусь. Возможно, он нужен для больших и высоконагруженных проектов, таких как банковские системы, но зачастую без него можно легко обойтись.
Поправьте, если не прав. Буду рад поговорить на эту тему с более опытными людьми.
MaxKyselov
25.05.2022 08:51В реальном приложении в функцию передаю переменные, которые приходят с бека или пользовательского ввода. Как решить вопрос синхронизации ответов бека и ваших TS интерфейсов?
Добавьте реальные минусы использования TS кроме плюсов в статью чтобы разработчик мог взвесить:
TS занимает не большую долю рынка (5-7% от всего js кода если не ошибаюсь)
Повышает порог вхождения в проект
Делает юнит тесты более трудоемкими
Делает написание сложных структур трудоемкими
Считаю целесообразным использование TS в пакетах компонентов (т.е. мы точно знаем какой тип будет у пользовательского ввода), фреймворков и т.д.
GebekovAS
В примерах и описании ошибки и опечатки. Объявляется функция concatenation, но в обоих примерах вызываешь sum.
нет, если в первом аргументе передать число, а во втором строку, мы в итоге все равно получим ожидаемую строку. Пример, кстати, получился "ошибочно верным" (Ошибка в том, что вызвали функцию sum, а верным указали в обоих аргументах число)