Myšlenky na TypeScript

Začátkem tohoto týdne společnost Microsoft vydala TypeScript 1 , nový jazyk kompilace do JavaScriptu pro „JavaScript v měřítku aplikací“. Moje první reakce byla zmatená:

Zdá se, že téměř každý týden se objeví nový jazyk, který se snaží nahradit JavaScript na webu. Google se setkal s vlažným přijetím, když představil Dart 2 , je to vlastní nápad na opravu všech vnímaných nedostatků JavaScriptu. CoffeeScript 3 je i nadále nejvýznamnější z těchto možností a často podněcuje svaté války online. A teď Microsoft hází klobouk do ringu a já se nestačil divit proč.

Moje zaujatost

Než budu mluvit konkrétně o TypeScript, chci vysvětlit svou osobní zaujatost, abyste mohli zbytek mých komentářů pojmout v jejich správném kontextu. V odvětví vývoje webu existuje velmi reálný problém a tím problémem je značný nedostatek dobrých vývojářů JavaScriptu. Nemohu vám sdělit počet společností, které mě kontaktují ve snaze najít nadprůměrné talenty na JavaScript pro práci na jejich aplikacích. Ano, nyní je mnohem kompetentnějších vývojářů JavaScriptu, než tomu bylo před 10 lety, ale poptávka se zvýšila způsobem, který daleko převyšuje nárůst nabídky. Jednoduše není dostatek lidí, kteří by zaplnili všechny dostupné úlohy JavaScriptu. To je problém.

Někdo by mohl namítnout, že vysoká poptávka a nízká nabídka staví dobré vývojáře JavaScriptu do skvělé pozice a my bychom to nikdy neměli chtít změnit. Koneckonců, proto můžeme požadovat platy, které děláme. Z osobního ekonomického hlediska souhlasím. Z hlediska potřeby zlepšit web nesouhlasím. Ano, chci si dobře vydělávat tím, co dělám, ale také chci, aby web jako celek i nadále rostl a zlepšoval se, a to se stane pouze tehdy, když mezi zaměstnance nastoupí kompetentnější vývojáři.

Jazyky kompilace do JavaScriptu vidím jako překážku k dosažení tohoto cíle. Měli bychom přesvědčovat více lidí, aby se naučili JavaScript, spíše než jim dávat více možností JavaScript nepsat. Často přemýšlím, co by se stalo, kdyby všechny týmy a společnosti, které vynaložily čas, energii, personál a peníze na vývoj těchto alternativ, místo toho použily tyto zdroje na vylepšení JavaScriptu a jeho výuku.

Aby bylo jasno, neříkám, že JavaScript je dokonalý jazyk a nemá své bradavice. Každý jazyk, který jsem kdy použil, má části, které jsou na hovno a části, které jsou úžasné, a JavaScript se neliší. Věřím, že JavaScript se musí vyvíjet, a to nutně přináší další části, které budou savé, stejně jako další části, které jsou úžasné. Přál bych si, abychom všichni vynakládali své úsilí ve stejné oblasti a nerozdělovali je na různé projekty.

Co je TypeScript?

Tento týden jsem strávil spoustu času prohlížením TypeScriptu, čtením dokumentace a sledováním videa na webu. Poté jsem byl pozván Rey Bango, abych se setkal s několika členy týmu TypeScript, abych odpověděl na své vlastní otázky. Se všemi těmito znalostmi mám pocit, že mám velmi dobrou představu o tom, co TypeScript je a co není.

TypeScript je především nadmnožinou JavaScriptu. To znamená, že můžete psát běžný JavaScript uvnitř TypeScriptu a je zcela platný. TypeScript přidává k JavaScriptu další funkce, které pak kompilátor TypeScript převede na kód kompatibilní s ECMAScript 5. Toto je zajímavý přístup, který se zcela liší od ostatních jazyků kompilujících do JavaScriptu. Namísto vytváření zcela nového jazyka s novými pravidly syntaxe začíná TypeScript s JavaScriptem a přidává další funkce, které do syntaxe docela dobře zapadají.

Ve své nejzákladnější podobě vám TypeScript umožňuje anotovat proměnné, argumenty funkcí a funkce pomocí informací o typu. Tyto dodatečné informace umožňují nástrojům poskytovat lepší automatické dokončování a kontrolu chyb, než jaké byste mohli získat pomocí běžného JavaScriptu. Syntaxe je vypůjčena z původního návrhu JavaScript 2/ECMAScript 4 4 který byl také implementován jako ActionScript 3:

var myName: string = "Nicholas";

function add(num1: number, num2: number): number {
    return num1 + num2;
}

function capitalize(name: string): string {
    return name.toUpperCase();
}

Syntaxe dvojtečky vám může připadat povědomá, pokud jste někdy používali Pascal nebo Delphi, přičemž oba používají stejnou syntaxi pro označení typu. Řetězce, čísla a booleany v JavaScriptu jsou v TypeScript reprezentovány jako string , number a bool (poznámka:všechna malá písmena). Tyto anotace pomáhají kompilátoru TypeScript zjistit, zda používáte správné hodnoty. Varování by způsobilo například následující:

// warning: add() was defined to accept numbers
var result = add("a", "b");

Od add() byl definován pro přijímání čísel, tento kód způsobí varování kompilátoru TypeScript.

TypeScript je také dostatečně chytrý, aby odvodil typy, když existuje přiřazení. Každé z těchto deklarací je například automaticky přiřazen typ:

var count = 10;           // assume ": number"
var name = "Nicholas";    // assume ": string"
var found = false;        // assume ": bool"

To znamená, že chcete-li získat nějaké výhody z TypeScriptu, nemusíte nutně všude přidávat typové anotace. Můžete se rozhodnout nepřidávat typové anotace a nechat kompilátor, aby se pokusil věci vyřešit, nebo můžete přidat několik typových anotací, které vám pomohou.

Snad nejúžasnější částí těchto anotací je schopnost správně anotovat funkce zpětného volání. Předpokládejme, že chcete spustit funkci pro každou položku v poli, podobnou Array.prototype.forEach() . Pomocí JavaScriptu byste definovali něco takového:

function doStuffOnItems(array, callback) {
    var i = 0,
        len = array.length;

    while (i < len) {
        callback(array[i], i, array);
        i++;
    }
}</code>

Funkce zpětného volání přijímá tři argumenty, hodnotu, index a samotné pole. Neexistuje žádný způsob, jak to zjistit, kromě čtení kódu. V TypeScriptu můžete anotovat argumenty funkce, aby byly konkrétnější:

function doStuffOnItems(array: string[], 
        callback: (value: string, i: number, array: string[]) => {}) {
    var i = 0,
        len = array.length;

    while (i < len) {
        callback(array[i], i, array);
        i++;
    }
}</code>

Tento kód přidává anotace k oběma argumentům doStuffOnItems() . První argument je definován jako pole řetězců a druhý argument je definován jako funkce přijímající tři argumenty. Všimněte si, že formát pro definování typu funkce je syntaxe funkce tlusté šipky ECMAScript 6. 5 Díky tomu může kompilátor zkontrolovat, zda se funkce shoduje s podpisem, než se kód vůbec spustí.

Typové anotace jsou skutečně jádrem TypeScriptu a toho, k čemu byl navržen. Díky těmto dodatečným informacím lze vytvořit editory, které nejen provádějí kontrolu typu kódu před jeho spuštěním, ale také poskytují lepší podporu automatického doplňování při kódování. TypeScript již má zásuvné moduly pro Visual Studio, Vim, Sublime Text 2 a Emacs, 6 takže existuje spousta možností, jak to vyzkoušet.

Další funkce

Zatímco hlavním bodem TypeScriptu je poskytnout JavaScriptu určitou zdání statického psaní, tím to nekončí. TypeScript také podporuje třídy ECMAScript 6 7 a moduly 8 (jak jsou aktuálně definovány). To znamená, že můžete napsat něco takového:

class Rectangle {
    constructor(length: number, width: number) {
        this.length = length;
        this.width = width;
    }

    area() {
        return this.length * this.width;
    }
}

A TypeScript to převede na toto:

var Rectangle = (function () {
    function Rectangle(length, width) {
        this.length = length;
        this.width = width;
    }
    Rectangle.prototype.area = function () {
        return this.length * this.width;
    };
    return Rectangle;
})();

Všimněte si, že funkce konstruktoru je vytvořena správně a jedna metoda je správně umístěna na prototyp.

Kromě modulů a tříd, TypeScript také zavádí schopnost definovat rozhraní. Rozhraní nejsou v ECMAScript 6 vůbec definována, ale jsou užitečná pro TypeScript, pokud jde o kontrolu typu. Protože kód JavaScript má tendenci mít definováno velké množství objektových literálů, rozhraní poskytují snadný způsob, jak ověřit, že je použit správný typ objektu. Například:

interface Point {
    x: number;
    y: number;
}

function getDistance(pointA: Point, pointB: Point) {
    return Math.sqrt( 
               Math.pow(pointB.x - pointA.x, 2) +
               Math.pow(pointB.y - pointA.y, 2)
           );
}

var result = getDistance({ x: -2, y: -3}, { x: -4, y: 4})

V tomto kódu je rozhraní nazvané Point se dvěma vlastnostmi x a y . getDistance() funkce přijímá dva body a vypočítává vzdálenost mezi nimi. Tyto dva argumenty mohou být libovolný objekt obsahující přesně tyto dvě vlastnosti x a y , což znamená, že mohu předat objektové literály a TypeScript zkontroluje, zda obsahují správné vlastnosti.

Rozhraní i třídy vstupují do typového systému a poskytují lepší kontrolu chyb. Moduly jsou jen způsoby, jak seskupit související funkce.

Co se mi líbí

Čím více jsem si hrál s TypeScriptem, tím více jsem nacházel jeho části, které se mi opravdu líbí. V první řadě se mi líbí, že v TypeScriptu můžete psát běžný JavaScript. Microsoft se nesnaží vytvořit úplně nový jazyk, snaží se užitečným způsobem rozšířit JavaScript. Dokážu to ocenit. Také se mi líbí, že se kód zkompiluje do běžného JavaScriptu, který skutečně dává smysl. Ladění kódu generovaného TypeScriptem není tak obtížné, protože používá známé vzory.

Nejvíce mě zaujalo to, co TypeScript nedělá. Nevypisuje kontrolu typu do vašeho kódu JavaScript. Všechny tyto typy poznámek a kontrola chyb jsou navrženy tak, aby je bylo možné používat pouze při vývoji. Konečný kód neprovádí žádnou kontrolu typu, pokud to neprovádíte ručně pomocí kódu JavaScript. Třídy a moduly se převedou na běžný JavaScript, zatímco rozhraní zcela zmizí. Ve finálním JavaScriptu se nikdy neobjeví žádný kód pro rozhraní, protože se používají výhradně během vývoje pro účely kontroly typu a automatického doplňování.

Integrace editoru pro TypeScript je docela dobrá. Stačí přidat pár anotací a rázem se v editoru rozsvěcují případné chyby a návrhy. Schopnost explicitně definovat očekávání pro funkce zpětného volání je obzvláště působivá, protože to je jedna oblast, ve které obvykle vidím spoustu problémů souvisejících s předáváním nesprávných hodnot do funkcí.

Také se mi líbí ten Microsoft open-source TypeScript. Zdá se, že jsou odhodláni to rozvíjet otevřeně a rozvíjet komunitu kolem TypeScript. Zda to dodrží a skutečně fungují jako open source projekt, se teprve uvidí, ale alespoň podnikli kroky, které tuto možnost umožňují.

Co se mi nelíbí

I když tleskám rozhodnutí Microsoftu používat třídy ECMAScript 6, obávám se, že to staví jazyk do obtížné pozice. Podle členů týmu TypeScript, se kterými jsem mluvil, plánují zůstat v synchronizaci se syntaxí ECMAScript 6 pro moduly a třídy. To je teoreticky skvělý přístup, protože povzbuzuje lidi, aby se naučili dovednosti, které budou užitečné v budoucnu. Ve skutečnosti je to obtížný návrh, protože ECMAScript 6 ještě není dokončen a neexistuje žádná záruka, že se syntaxe před dokončením specifikace znovu nezmění. To staví tým TypeScript do velmi obtížné pozice:pokračovat v aktualizaci syntaxe, aby odrážela současnou realitu ECMAScript 6, nebo zaostávat (možná fork?), aby bylo jejich vývojové prostředí stabilní.

Totéž platí pro typové anotace. Přestože existuje značná předchozí práce naznačující, že syntaxe dvojtečky bude fungovat v JavaScriptu, neexistuje žádná záruka, že bude někdy přidána do jazyka. To znamená, že to, co TypeScript aktuálně dělá, může skončit v rozporu s tím, co nakonec dělá ECMAScript. To také povede k rozhodnutí, kterou cestou se vydat.

Tým TypeScript doufá, že se kolem jazyka a nástrojů vyvine komunita, která jim pomůže informovat o tom, jakým směrem se vydat, když se objeví taková rozhodnutí. To je také dvousečná zbraň. Pokud se jim podaří vytvořit rozsáhlou komunitu kolem TypeScriptu, je velmi pravděpodobné, že se komunita může rozhodnout, že bude chtít opustit standard ECMAScript, spíše než u něj zůstat, kvůli vysokým nákladům na údržbu upgradu stávajícího kódu.

A opravdu nemám rád primitivní typ s názvem bool . Už jsem jim řekl, že bych rád viděl, že se to změnilo na boolean takže se mapuje zpět na hodnoty vrácené z typeof , spolu s string a number .

Měli byste to použít?

Myslím, že TypeScript má mnoho slibů, ale mějte na paměti jednu věc:současná nabídka je časná verze alfa. Možná to tak nevypadá z webu, který je docela vybroušený, ani z pluginů editoru, nebo ze skutečnosti, že číslo verze je uvedeno 0.8.0, ale potvrdil jsem týmu TypeScript, že to považují za velmi rané experimentální vydání, které vývojářům poskytne náhled na to, co přichází. To znamená, že se věci mohou během příštího roku výrazně změnit, než se TypeScript stabilizuje (pravděpodobně jako ECMAScript 6 stabilizuje).

Vyplatí se to tedy nyní používat? Řekl bych, že pouze experimentálně a poskytnout zpětnou vazbu týmu TypeScript. Pokud se rozhodnete používat TypeScript pro svou běžnou práci, činíte tak na vlastní nebezpečí a důrazně doporučuji, abyste se drželi používání typových anotací a rozhraní výhradně, protože jsou odstraněny z kompilovaného kódu a je méně pravděpodobné, že se změní, protože spolu přímo nesouvisejí. na ECMAScript 6. Vyhnul bych se třídám, modulům a všemu, co aktuálně není podporováno v ECMAScript 5.

Závěr

TypeScript nabízí něco velmi odlišného od ostatních jazyků pro kompilaci do JavaScriptu v tom, že začíná JavaScriptem a přidává k němu další funkce. Jsem rád, že běžný JavaScript lze psát v TypeScriptu a stále těžit z některých kontrol typu, které poskytuje kompilátor TypeScript. To znamená, že psaní TypeScriptu může lidem skutečně pomoci naučit se JavaScript, což mě těší. Není pochyb o tom, že tyto typy poznámek mohou při integraci s editory vytvořit lepší vývojový zážitek. Jakmile bude ECMAScript 6 dokončen, vidím velké využití pro TypeScript, který umožňuje vývojářům psát kód ECMAScript 6, který bude stále fungovat v prohlížečích, které jej nativně nepodporují. Do té doby jsme ještě hodně daleko, ale mezitím stojí za to TypeScript sledovat.

Odkazy

  1. TypeScript (typescriptlang.org)
  2. Dart (dartlang.org)
  3. CoffeeScript (coffeescript.org)
  4. Navrhovaný ECMAScript 4th Edition – Language Overview (ECMA)
  5. Syntaxe funkce šipky ECMAScript 6 (ECMA)
  6. Sublime Text, Vi, Emacs:TypeScript povolen! (MSDN)
  7. ECMAScript 6 Maximally Minimal Classes (ECMA)
  8. Moduly ECMAScript 6 (ECMA)