Сегондя мы анонсируем альфа-версию TypeScript 1.5, первую превью-версию предстоящего релиза TS1.5. Эта версия дает возможность познакомиться со многими новыми возможностями, которые мы планируем включить в финальный релиз.



Три ключевые новые вещи, которые мы добавляем в инструменты TypeScript: более богатый опыт работы с ES6, декораторы и новый плагин для Sublime Text.

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

Улучшенный опыт работы с ES6


В TypeScript 1.5 мы добавили несколько новых возможностей ES6. Эти возможности мы связали с системой типов TypeScript, чтобы дать вам дополнительную поддержку в инструментах при работе с новыми шаблонами написания кода, присущими ES6.

Модули


Синтаксис модулей в ES6 — это мощный путь для работы с модулями. Вы можете взаимодействовать с ними, импортируя модуль целиком или работая с отдельными импортируемыми сущностями.

import * as Math from "my/math";
import { add, subtract } from "my/math";


ES6 также поддерживает ряд возможностей для указания экспоритуемых элементов. Вы можете выставлять такие декларации, как классы или функции. Вы также можете экспортировать «default», чтобы импортировать из модуля напрямую. Например:

// math.ts

export function add(x, y) { return x + y }
export function subtract(x, y) { return x – y }
export default function multiply(x, y) { return x * y }

// myFile.ts

import {add, subtract} from "math";
import times from "math";
var result = times(add(2, 3), subtract(5, 3));


Если вы уже использовали TypeScript, вы можете заметить, что это очень похоже на собственные внешние модули TypeScript. Это не случайность: когда мы создавали синтаксис внешних модулей в TS, мы работали над теми же сами проблемами. Однако дизайн ES6 расширяет эти возможности еще дальше, демонстрируя мощный и зрелый дизайн. Мы продолжим поддерживать внешние модули TS, но при этом призываем разработчиков начать использовать более мощный синтаксис модулей из ES6.

Деструктурирование


Деструктурирование (destructuring) — это удобная новая возможность, которая появляется в TS как часть нашей поддержки стандарта ES6. С его помощью вы можете разделять или разрушать объекты и массивы.

var [x, y] = [10, 20];
[x, y] = [y, x];  // a simple swap


Вы можете также использовать разрушение для управления параметрами функции:

var myClient = {name: "Bob", height: 6};
function greetClient({name, height: howTall}) {
  console.log("Hello, " + name + ", who is " + howTall + " feet tall.");
}
greetClient(myClient); 


В примере выше функция greetClient принимает единый объект со свойствами name и height. Используя синтаксис 'height: howTall', мы можем переименовать своейство height в howTall внутри greetClient.

И еще...


Мы также добавили поддержку for-of для улучшения итераций, компиляцию let/const в ES5, поддержку юникода, режим выдачи ES6-кода и внедрили улучшения в поддержке вычисляемых свойств.

Декораторы


Мы работаем с командами Angular, Ember и Aurelia (от создателей Durandal) над предложением по декораторам в ES7, превью которых мы добавили в альфа-версию TypeScript 1.5. Декораторы позволяют вам четко указывать особенности кода. В примере ниже мы видим, как декоратор @memoize может быть использован для обозначения, что пара геттера и сеттера может быть мемоизирована:

class Person {
  @memoize
  get name() { return `${this.first} ${this.last}` }

  set name(val) {
    let [first, last] = val.split(' ');
    this.first = first;
    this.last = last;
  }
}


Разработчики смогут создавать новые декораторы и смешивать их при работе с системой типов.

Плагин для Sublime Text




Вместе с альфа-версией TypeScript 1.5 мы также выпускаем превью плагина для Sublime Text для работы с TypeScript, чтобы у тех разработчиков, которые пользуются данным редактором, также была возможность работать с TypeScript. Этот плагин работает как с Sublime Text 2, так и с Sublime Text 3 и дает возможность почувствовать, какие преимущества дает система типов из TypeScript. Sublime Text и плагин TypeScript доступны для OSX, Linux и Windows.


Команды TypeScript, доступные в Sublime Text

Плагин для Sublime Text позволяет вам легко перемещаться по коду, осуществлять рефакторинг, форматирование и исследование кода. Для тех, кто пробовал плагин, который был показан во время демонстрации на ng-conf, обновленный плагин покажется заметно более шустрым, особенно на больших файлах.

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

Что дальше


Данная альфа-версия показывает, что будет возможным делать на TypeScript 1.5, когда он будет выпущен, — и мы очень хотим узнать, что вы об этом думаете. Мы активно работаем над TS1.5 — и вы можете помочь нам сделать этот релиз лучше, пробуя его и рассказывая нам о любых проблемах, с которыми вы столкнетесь.

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


  1. k12th
    03.04.2015 16:47
    +2

    Итераторов и генераторов пока нету?


    1. kichik Автор
      03.04.2015 16:52
      +2

      1. k12th
        03.04.2015 16:53
        +1

        Спасибо.


  1. dom1n1k
    03.04.2015 17:14
    -1

    Прочитал недавно всю спецификацию — в целом язык понравился.
    Правда, создалось ощущение, что полезен он будет только в режиме «полного цикла» — то есть когда на нем пишется большой проект, целиком от начала до конца.
    Писать на нем, например, библиотеку общего назначения вроде как бессмысленно.


    1. kichik Автор
      03.04.2015 17:22

      Ну для библиотеки как раз это имеет большой смысл в двух аспектах: проектирование API и выставление его наружу с подсказками для редактора через .d.ts.

      Вот пример ребят из Wix: blogs.msdn.com/b/typescript/archive/2015/03/17/guest-post-gil-amran-talks-about-using-typescript-at-wix.aspx. Внутренние функции хоть на голом JS, а на стыках TS.


      1. dom1n1k
        03.04.2015 17:27

        Про .d.ts знаю, но это для других пользователей TS.
        А я другое имел в виду: писать на TS библиотеку, которую потом будут использовать разные люди, пишущие в других окружениях (ванильный JS, CS, LS и пр). В этом случае особо большого смысла не видно.


    1. Vestild
      03.04.2015 17:24
      -1

      Если к библиотеке идёт .d.ts файл, это сильно облегчает её понимание. Это так, на всякий случай.


    1. impwx
      03.04.2015 17:44
      -1

      Почему же, очень практично. Исходный код библиотеки будет на TS со всеми плюшками, а все остальные могут использовать скомпилированный js-вариант. Примерно так команды Angularjs \ Ember \ остальных фреймворков и работают.


  1. btd
    03.04.2015 19:17
    +1

    Я может быть не в тему. Я видел в ts репозитории issue на добавление типов числе переменной длины (i8 — int8, uint, int и тд). Не знаете, планируется что нибудь такое добавить. Понятно, что это здоровенный костыль в js, но сделало бы типобезопасную работу проще с битовыми операциями.
    И я даже очень понимаю насколько это не популярно, и может понадобится весьма не часто. Но просто реальных альтернатив я не нашел, самое близкое это asm.js — но его руками не напишешь.


    1. Eternalko
      04.04.2015 17:50

      Почему костыль? Разработчики на JS уже давно используют типизацию на полную катушку.
      Там где есть необходимость.

      Вот тут можно ознакомиться с фундаментом: Typed Array.
      Есть полно библиотек которые добавляют сахару (удобства) использования.

      asm.js, кстати, тоже через них работает.


      1. btd
        04.04.2015 19:06

        Костыль потому что в яваскрипте самом нет такой типизации. А что я хочу я думаю лучше объяснить на примере:

        let a: int8 = 150
        let b: int8 = 200

        Я хочу чтобы в результате было для
        a | b
        (a | b) & 0xFF


        1. Eternalko
          04.04.2015 20:52
          +1

          var a, b, c, typed;
          typed = new Uint8Array(new ArrayBuffer(2));
          typed[0] = 150;
          typed[1] = 200;
          typed[2] = 300; // # undefined. Only 2 bytes allocated
          
          a = typed[0] | typed[1]; // 222
          b = (typed[0] | typed[1]) & 0xFF; // 222 ?
          c = parseInt(d, 16); // 546
          

          Оно?

          Не совсем понимаю что вы хотите получить в результате.


          1. btd
            04.04.2015 22:27
            +1

            Да, оно! Я честно говоря не думал, о таком использовании typed arrays. Спасибо хорошая идея.


            1. Eternalko
              04.04.2015 22:44
              -2

              На здоровье (:

              По опыту добавлю небольшой TL;DR.

              — Читайте доки начиная с MDN. Там ИМО лучше всего.
              ArrayBuffer — просто определяет кусок памяти в байтах
              TypedArray (Uint8Array/Uint16Array/...) — просто предоставляет доступ к этим байтам в каком-то формате. Мы как бы говорим JS как их читать. Cast view, так сказать.
              DataView — мне не понравился чем-то. Вроде как новый стандарт, который не взлетел.

              Вот как можно использовать. Внимание, СoffeScript (не люблю скобочки и ";")

              # Создаем рандомный binary.
              module.exports.getRandomBuffer = (mb = 1) ->
                  buffer = new ArrayBuffer(mb * 1024 * 1024 )
                  i8 = new Int32Array(buffer)
              
                  i = 0
                  while i < i8.length
                      i8[i] = Math.random() * 100 | 0
                      i++
              
                  return buffer
              
              # Считаем тупой но быстрый хеш:
              module.exports.noobHash = (arg) ->
                  i8 = new Int32Array(arg)
                  hash = 0
                  i = 0
                  while i < i8.length
                      hash += i8[i]
                      i++
                  return hash
              


  1. UnknownHero
    03.04.2015 22:35
    +2

    Теперь ждём async/await.
    Хотя и с промисами хорошо идёт.


    1. Eternalko
      04.04.2015 17:53

      А зачем вам async/await? Просто самому приходится постоянно иметь делать с асинхронностью и я не понимаю проблемы/потребности.


      1. a553
        04.04.2015 22:44

        1. Eternalko
          04.04.2015 22:57
          -1

          Это не совсем ответ. Вот быстрый рефактор.

          fs.readdir source, (err, files) ->
              if err then console.log 'Error finding files: ' + err; return 
          
              files.forEach (filename, fileIndex) ->
                  console.log filename
                  gm(source + filename).size (err, values) ->
                      if err then console.log 'Error identifying file size: ' + err; return
          
                      console.log filename + ' : ' + values
                      aspect = values.width / values.height
          
                      widths.forEach (width, widthIndex) =>
                          height = Math.round(width / aspect)
                          console.log 'resizing ' + filename + 'to ' + height + 'x' + height
                          @resize(width, height).write destination + 'w' + width + '_' + filename, (err) ->
                              if err then console.log 'Error writing file: ' + err
          


          А вообще тут вполне можно разделить вещи на отдельные функции и все.
          async/await тут не помогут


          1. a553
            04.04.2015 23:04
            +3

            А теперь нормальный, читаемый код:

            try {
                await fs.readdir(source, defer files);
            
                await files.forEach(defer filename, defer fileIndex);
            
                console.log(filename)
            
                await gm(source + filename).size(defer values);
            
                console.log(filename + ' : ' + values)
                aspect = (values.width / values.height)
            
                await widths.forEach(defer width, defer widthIndex);
            
                height = Math.round(width / aspect)
                console.log('resizing ' + filename + 'to ' + height + 'x' + height)
            
                await this.resize(width, height).write(destination + 'w' + width + '_' + filename, defer _);
            
            } catch (e) {
                console.log(e);
            }
            
            


            1. Eternalko
              04.04.2015 23:22

              Теперь понятней. Спасибо.
              Лично для меня он менее читаем, но это скорее всего привычка.
              Действительно, у такого подхода, во многих ситуациях есть потенциал.

              Вот еще равнозначный код:

              source
              try
                  fs.readdir source, (files) ->
                      files.forEach (filename, fileIndex) ->
                          console.log filename
                          gm(source + filename).size (values) ->
                              console.log filename + ' : ' + values
                              aspect = values.width / values.height
              
                              widths.forEach (width, widthIndex) =>
                                  height = Math.round(width / aspect)
                                  console.log 'resizing ' + filename + 'to ' + height + 'x' + height
                                  @resize(width, height).write destination + 'w' + width + '_' + filename
              catch (e)
                  console.log e
              


              1. a553
                04.04.2015 23:25
                +1

                Это ошибочный код. Исключения у вас не ловятся.

                Более красивая и каноничная версия async/await есть в ES7, но она совместима только с Promise.


                1. Eternalko
                  11.04.2015 00:58

                  С опозданием благодарю за разъяснения и наводку на такой подход.
                  Нашел кучу библиотек которые таким занимаются. Пока немного сыровато, но в в общем у такого подхода есть много положительных нюансов.


              1. symbix
                05.04.2015 18:42

                Вы читерите немного. Перепишите на чистом JS (function function function function!, хотя тут в TS тоже есть сахарок со стрелочкой, хоть и не равнозначный), и добавьте полноценную обработку исключений из колбэков — тогда сравнение будет равноценным.

                Promise/deferred проблему решают, но с await все же намного короче и читаемее.

                Кофескрипт же справедливее будет сравнивать с IcedCoffee.


                1. Eternalko
                  11.04.2015 01:02

                  В ES6 уже тоже есть стрелочки, так что не совсем чит. Все коллеги что из JS уже пишут в ES6 стрелочками и ок.
                  Тут только скобочек нет, всего навсего.

                  Await & ICS хорошие. ICS действительно делает много финтов ушами, особенно там, где это связано с циклами.
                  Приятно. Однако в работе я бы пока этого не использовал.


  1. babylon
    04.04.2015 01:23
    +2

    TypeScript это самое полезное, что сделал майкрософт за долгое время.


  1. symbix
    04.04.2015 05:34

    Я правильно понимаю, что с реализацией ES6 modules можно забыть про ад с ///<reference>? Если так — это просто супер.


    1. Voronar
      06.04.2015 00:33

      Я правильно понимаю, что ES6-модули можно будет компилировать как в виде внутренних модулей а-ля "///reference" (тупо последовательное слияние файлов), так и в виде внешних(RequireJS, CommonJS, pure ES6)?


      1. symbix
        06.04.2015 15:08

        Похоже, так.

        TypeScript supports down-level compilation of external modules using the new ES6 syntax.

        When compiling with -t ES3 or -t ES5 a module format must be chosen using -m CommonJS or -m AMD.

        When compiling with -t ES6 the module format is implicitly assumed to be ECMAScript 6 and the compiler simply emits the original code with type annotations removed.

        (https://github.com/Microsoft/TypeScript/issues/2242)

        Насчет последовательного слияния не очень понятно, но не очень-то и надо, для этого есть gulp (или grunt, если кому нравится больше).