Миграция с CoffeeScript на TypeScript

Встала задача — довольно большой проект, написанный на CoffeeScript, перенести на TypeScript.
Не смотря на мою симпатию к свободному от громоздкости coffee я этому «челенджу» обрадовалась.

Почему? Давайте рассмотрим оба языка:

Coffee

Плюсы — краткость кода, и большое количество удобных фич.

Минус — несмотря на приближение к ES6 (в плане фич) это все же не ES6. Так как проблемы решались через изменение синтаксиса

Тут можно посмотреть CoffeeScript эквиваленты.ES6,

А хорошо бы уже наконец использовать все преимущества стандарта,. Благо сейчас нет никакой проблемы затем преобразовать написанный код в ES5, поддерживаемый браузерами.

Так что возможно писать на coffeeScript имеет смысл только, если ценность краткости кода превыше всего.

Так может писать на ES6, а потом траслировать в удобоваримый для браузеров ES5?

Если не видите для себя в типизации преимущества, то тогда скорее подходит такой вариант.

Иначе — TypeScript.

TypeScript

Можно писать на es6.
Код в процессе трансляции преобразуется в es5 (если указать в настройках).
И даже никакой дополнительный транспайлер не нужен.
Да и вообще любой js код — валидный ts.

Указание типов позволяет на этапе компиляции TS проверить код на ошибки.

Мы можем выбрать нужно ли нам уведомления об ошибке, если где-то не поставили тип.
Для этого существует параметр noImplicitAny.
По умолчанию false, а если true, то будет выводить сообщение об ошибке «TS7006 Parameter implicitly has an ‘any’ type».
Параметр прописывается в файле tsconfig.json.

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

Еще в интернете порой всплывает мнение, что если вы используете Angular2, то обязательно с ним в связке должны использовать и TS.
Но нет, Angular2 прекрасно работает и с ES5, ES6 и Dart.

Подробнее про Angular2 и TS.

Как перейти на TypeScript

Дано:

  • проект на angular1.5
  • код написан на coffee
  • собирается все с помощью gulp,
  • IDE — Webstorm 16.3 .

План: постепенно перейти на TS.

Реализация:

Как только поступила задача по изменению одного сервиса, я поcчитала момент подходящим.
1. Установила «typescript»: «^2.1.4» и «gulp-typescript»: «^3.1.4» — компилятор typescript для  gulp.

npm install typescript --save-dev

npm install gulp-typescript --save-dev

2. Загрузила TypeScript определение (definitions) для ангуляра

npm install --save-dev @types/angular

3 Заменила coffee файл сервиса на ts с js кодом, который траслировался из coffee файла.

4. Переписала код на es6.

Упрощенный пример приведен ниже:

class Friends {
    constructor(public ipCookie) {

    }
    get() {
        if (this.ipCookie('friend_ref')) {
            return this.ipCookie('friend_ref');
        }
        return false;
    }
    set (value: String) {
        let domain;
        domain = window.location.host.match('site.ru') ? '.site.ru' : '';
        return this.ipCookie('friend_ref', value, {
            path: '/',
            domain: domain,
            expires: 1
        });
    }

}

angular.module('front.friends', []).service('Friends',Friends);

Как видите я в конструктор передала сервис ipCookie, чтобы иметь к нему доступ.

В функции set определила, что параметр value должен быть строкой. Если я попытаюсь с этой переменной сделать что-то непотребное вроде: value = value^2, то получу ошибку. Соответственно и вызов метода с параметром отличным от строки, вызовет ошибку.

5. Написала gulp задачу:

 
gulp.task('ts', function() {
    var ts =  $.typescript;
    return gulp.src('app/scripts/**/*.ts')
        .pipe(ts({ target: "es5"}))
        .js.pipe(gulp.dest('.tmp/scripts/'))
});

gulp.src(‘app/scripts/**/*.ts’) — возвращается поток TS файлов.
.pipe(ts({ target: «es5»})) — передаются настройки
.js.pipe(gulp.dest(‘.tmp/scripts/’)) — полученные js файлы записываются в папку .tmp.

У меня настроек немного, поэтому я их прям тут и прописала.

Если настройки хотите прописать в файле tsconfig.json, то тогда нужно его передать:

 

gulp.task('ts', function() {
    var ts = $.typescript;
    var tsProject = ts.createProject('./tsconfig.json');
    return gulp.src('app/scripts/**/*.ts')
        .pipe(tsProject())
        .js.pipe(gulp.dest('.tmp/scripts/'))
});
 

tsProject — на основе файла tsconfig.json создается объект с настройками.
gulp.src(‘app/scripts/**/*.ts’) — возвращается поток TS файлов.
.pipe(tsProject()) — передаются настройки
.js.pipe(gulp.dest(‘.tmp/scripts/’)) — полученные js файлы записываются в папку .tmp.

5. Если хотим прописывать настройки в файл tsconfig.json,то он бы мог выглядеть в данном случае так:


{
  "compilerOptions": {
    "target": "es5",
    "outDir": "./.tmp/scripts/"
  },
  
  "include": [
     "app/scripts/**/*.ts"
  ]

}

«target» — в каком виде выводить js. Мне важна поддержка браузеров, поэтому перевожу es6 код в es5.
«outDir» — куда выводить
«include» — какие файлы включать. Понадобилось прописывать, так как иначе появлялись ошибки по ts файлам компонентов bower и node модулей.

6. В настройках шторма

tsStorm

Важный момент — как раз в последних версиях webStorm улучшена поддержка TS, так что это тот случай, когда версия IDE имеет большое значение. На 16.2  у меня возникли сложности с компиляцией ts в js.

 

Почитать

Understanding ES5, ES2015 and TypeScript
Why You Shouldn’t Be Scared of TypeScript
TypeScript vs. CoffeeScript vs. ES6

Хотите быть в курсе новых статей?