Che cos’è TypeScript e perché dovrei usarlo al posto di JavaScript?

Puoi descrivere quale è il linguaggio TypeScript?

Cosa può fare che JavaScript o le librerie disponibili non possono fare, che mi darebbe motivo per considerarlo?

Ho originariamente scritto questa risposta quando Typescript era ancora hot-off-the-presses. Cinque anni dopo, questa è una buona panoramica, ma guarda la risposta di Lodewijk qui sotto per maggiori informazioni

Vista di 1000 piedi …

TypeScript è un superset di JavaScript che fornisce principalmente tipizzazione, classi e interfacce statiche opzionali. Uno dei grandi vantaggi consiste nel consentire agli IDE di fornire un ambiente più ricco per individuare errori comuni durante la digitazione del codice .

Per avere un’idea di cosa intendo, guarda il video introduttivo di Microsoft sulla lingua.

Per un grande progetto JavaScript, l’adozione di TypeScript potrebbe risultare in un software più robusto, pur essendo distribuibile dove dovrebbe essere eseguita un’applicazione JavaScript regolare.

È open source, ma ottieni l’intelligente Intellisense mentre scrivi se usi un IDE supportato. Inizialmente, questo era solo Visual Studio di Microsoft (notato anche nel post del blog di Miguel de Icaza ). In questi giorni, altri IDE offrono anche il supporto per TypeScript .

Ci sono altre tecnologie come questa?

C’è CoffeeScript , ma in realtà ha uno scopo diverso. IMHO, CoffeeScript fornisce la leggibilità per gli umani, ma TypeScript fornisce anche una leggibilità profonda per gli strumenti attraverso la sua tipizzazione statica opzionale (vedi questo post del blog recente per un po ‘più di critica). C’è anche Dart, ma questo è un sostituto completo per JavaScript (anche se può produrre codice JavaScript )

Esempio

Ad esempio, ecco alcuni TypeScript (puoi giocare con questo nel campo di gioco TypeScript )

class Greeter { greeting: string; constructor (message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } } 

Ed ecco il JavaScript che produrrebbe

 var Greeter = (function () { function Greeter(message) { this.greeting = message; } Greeter.prototype.greet = function () { return "Hello, " + this.greeting; }; return Greeter; })(); 

Si noti come TypeScript definisce il tipo di variabili membro e i parametri del metodo di class. Questo viene rimosso quando si traduce in JavaScript, ma viene usato dall’IDE e dal compilatore per individuare errori, come passare un tipo numerico al costruttore.

È anche in grado di dedurre tipi che non sono esplicitamente dichiarati, ad esempio, determinerebbe il metodo greet() restituisce una stringa.

Debugging Typescript

Molti browser e IDE offrono supporto per il debug diretto tramite sourcemaps. Consulta questa domanda sull’overflow dello stack per ulteriori dettagli: esegui il debug del codice TypeScript con Visual Studio

Voglio sapere di più?

Ho originariamente scritto questa risposta quando Typescript era ancora hot-off-the-presses. Controlla la risposta di Lodewijk a questa domanda per ulteriori dettagli.

Anche se la risposta accettata va bene, a questo punto ho sentito che non rende giustizia a TypeScript. Non sono più i primi tempi. TypeScript sta trovando molta più adozione ora con diversi framework popolari scritti in TypeScript. I motivi per cui dovresti scegliere TypeScript invece di JavaScript ora sono molti.

Relazione con JavaScript

JavaScript è standardizzato attraverso gli standard ECMAScript. Non tutti i browser in uso supportano tutte le funzionalità dei nuovi standard ECMAScript (vedere questa tabella ). TypeScript supporta i nuovi standard ECMAScript e li compila su target ECMAScript (più vecchi) a tua scelta (gli attuali target sono 3, 5 e 6 [ovvero 2015]). Ciò significa che è ansible utilizzare le funzionalità di ES2015 e oltre, come moduli, funzioni lambda, classi, l’operatore di diffusione, destrutturazione, oggi. Naturalmente aggiunge anche il supporto per il tipo, che non fa parte di alcuno standard ECMAScript e probabilmente non sarà mai dovuto alla natura interpretata invece della natura compilata di JavaScript. Il sistema di tipi di TypeScript è relativamente ricco e include: interfacce, enumerazioni, tipi ibridi, generici, tipi di unione e intersezione, modificatori di accesso e molto altro. Il sito Web ufficiale di TypeScript offre una panoramica di queste funzionalità.

Relazione con altri linguaggi di targeting JavaScript

TypeScript ha una filosofia unica rispetto ad altri linguaggi che compongono JavaScript. Il codice JavaScript è un codice TypeScript valido; TypeScript è un superset di JavaScript. Puoi quasi rinominare i tuoi file .js file .ts e iniziare a usare TypeScript (vedi “Interoperabilità JavaScript” sotto). I file TypeScript sono compilati in JavaScript leggibile, in modo che la migrazione sia ansible e la comprensione del TypeScript compilato non è affatto difficile. TypeScript si basa sui successi di JavaScript migliorando allo stesso tempo i suoi punti deboli.

Da un lato, si dispone di strumenti a prova di futuro che prendono i moderni standard ECMAScript e li compilano nelle versioni JavaScript più vecchie con Babel che è il più popolare. D’altra parte, ci sono linguaggi che possono differire totalmente da JavaScript che targetizzano JavaScript, come Coffeescript, Clojure, Dart, Elm, Haxe, ScalaJs e un intero host in più (vedi questo elenco ). Questi linguaggi, anche se potrebbero essere migliori di quelli che il futuro di JavaScript potrebbe mai portare, corrono un rischio maggiore di non trovare abbastanza adozione per garantire il loro futuro. Potresti anche avere più problemi nel trovare sviluppatori esperti per alcune di queste lingue, anche se quelle che troverai spesso possono essere più entusiaste. Interop con JavaScript può anche essere un po ‘più complicato, dal momento che sono più lontani da ciò che JavaScript è in realtà.

TypeScript si colloca tra questi due estremi, bilanciando così il rischio. TypeScript non è una scelta azzardata da nessuno standard. Ci vuole davvero poco per abituarsi se si ha familiarità con JavaScript, dal momento che non è una lingua completamente diversa, ha un eccellente supporto di interoperabilità JavaScript e ha visto un sacco di adozione di recente.

Facoltativamente digitazione statica e inferenza del tipo

JavaScript è digitato in modo dinamico. Ciò significa che JavaScript non sa che tipo è una variabile fino a quando non viene effettivamente istanziata in fase di esecuzione. Ciò significa anche che potrebbe essere troppo tardi. TypeScript aggiunge il supporto del tipo a JavaScript. I bug causati da false supposizioni di alcune variabili di un certo tipo possono essere completamente sradicati se giochi bene le tue carte (quanto sei severo nel digitare il tuo codice o se scrivi il tuo codice dipende solo da te).

TypeScript rende la digitazione un po ‘più semplice e molto meno esplicita dall’uso dell’inferenza di tipo. Ad esempio: var x = "hello" in TypeScript è lo stesso di var x : string = "hello" . Il tipo è semplicemente dedotto dal suo utilizzo. Anche se non si digita esplicitamente i tipi, sono ancora lì per evitare di fare qualcosa che altrimenti si tradurrebbe in un errore di runtime.

TypeScript è facoltativamente digitato per impostazione predefinita. Per esempio la function divideByTwo(x) { return x / 2 } è una funzione valida in TypeScript che può essere chiamata con qualsiasi tipo di parametro, anche se chiamarlo con una stringa risulterà ovviamente in un errore di runtime . Proprio come sei abituato in JavaScript. Funziona, perché quando nessun tipo è stato assegnato esplicitamente e il tipo non può essere dedotto, come nell’esempio divideByTwo, TypeScript assegnerà implicitamente il tipo any . Ciò significa che la firma del tipo della function divideByTwo(x : any) : any diventa automaticamente la function divideByTwo(x : any) : any . C’è un flag del compilatore per disabilitare questo comportamento: --noImplicitAny . Abilitare questo flag ti dà un maggior grado di sicurezza, ma significa anche che dovrai fare più digitazione.

I tipi hanno un costo associato a loro. Prima di tutto c’è una curva di apprendimento, e in secondo luogo, ovviamente, ti costerà un po ‘più di tempo per impostare una base di codice usando anche la tipizzazione corretta. Nella mia esperienza, questi costi valgono la pena su qualsiasi base di codice seria che si condivide con gli altri. Uno studio su larga scala dei linguaggi di programmazione e della qualità del codice in Github suggerisce che “le lingue tipizzate staticamente sono meno inclini ai difetti rispetto ai tipi dinamici, e che una digitazione forte è meglio di una digitazione debole nello stesso senso”.

È interessante notare che questo stesso documento trova che TypeScript è meno sobject a errori quindi JavaScript:

Per quelli con coefficienti positivi possiamo aspettarci che la lingua sia associata a, ceteris paribus, un numero maggiore di correzioni di errori. Questi linguaggi includono C, C ++, JavaScript , Objective-C, Php e Python. Le lingue Clojure, Haskell, Ruby, Scala e TypeScript hanno tutti coefficienti negativi, il che implica che questi linguaggi sono meno probabili della media per causare il commit dei difetti.

Supporto IDE migliorato

L’esperienza di sviluppo con TypeScript è un notevole miglioramento rispetto a JavaScript. L’IDE viene informato in tempo reale dal compilatore TypeScript sulle sue informazioni di tipo ricco. Questo dà un paio di importanti vantaggi. Ad esempio, con TypeScript è ansible eseguire in modo sicuro i refactoring come i nomi nell’intera codebase. Tramite il completamento del codice è ansible ottenere aiuto in linea su qualsiasi funzione possa offrire una libreria. Non è più necessario ricordarli o cercarli nei riferimenti online. Gli errori di compilazione vengono riportati direttamente nell’IDE con una linea ondulata rossa mentre si è impegnati nella codifica. Tutto sumto, ciò consente un significativo aumento della produttività rispetto al lavoro con JavaScript. Si può dedicare più tempo alla codifica e meno tempo al debugging.

Esiste una vasta gamma di IDE che hanno un eccellente supporto per TypeScript, come Visual Studio e codice VS, Atom, Sublime e IntelliJ / WebStorm.

Controlli nulli rigorosi

Errori di runtime del modulo cannot read property 'x' of undefined o undefined is not a function sono molto comunemente causate da bug nel codice JavaScript. Out of the box TypeScript riduce già la probabilità che si verifichino questi tipi di errori, poiché non è ansible utilizzare una variabile che non è nota al compilatore TypeScript (ad eccezione delle proprietà di any variabile tipizzata). È comunque ansible utilizzare erroneamente una variabile impostata su undefined . Tuttavia, con la versione 2.0 di TypeScript è ansible eliminare questi tipi di errori tutti insieme attraverso l’utilizzo di tipi non annullabili. Questo funziona come segue:

Con il rigoroso controllo nullo abilitato ( --strictNullChecks compilatore --strictNullChecks ) il compilatore TypeScript non consentirà l’assegnazione di un valore undefined a una variabile, a meno che non si dichiari esplicitamente il tipo nullable. Ad esempio, let x : number = undefined comporterà un errore di compilazione. Questo si adatta perfettamente alla teoria dei tipi, dal momento che undefined non è un numero. Si può definire x come un tipo di sum di number e undefined per correggere questo: let x : number | undefined = undefined let x : number | undefined = undefined .

Quando un tipo è noto come annullabile, ovvero è di un tipo che può anche essere del valore null o undefined , il compilatore TypeScript può determinare tramite l’analisi del tipo basato sul controllo del stream indipendentemente dal fatto che il codice possa o meno utilizzare una variabile in modo sicuro. In altre parole, quando si controlla che una variabile undefined sia undefined ad esempio un’istruzione if il compilatore TypeScript dedurrà che il tipo in quel ramo del stream di controllo del codice non è più annullabile e quindi può essere tranquillamente utilizzato. Qui c’è un semplice esempio:

 let x: number | undefined; if (x !== undefined) x += 1; // this line will compile, because x is checked. x += 1; // this line will fail compilation, because x might be undefined. 

Durante il co-progettista della conferenza di configurazione del 2016 di TypeScript Anders Hejlsberg ha fornito una spiegazione dettagliata e una dimostrazione di questa funzione: video (dalle 44:30 alle 56:30).

Compilazione

Per utilizzare TypeScript è necessario un processo di compilazione per compilare il codice JavaScript. Generalmente il processo di compilazione richiede solo un paio di secondi, a seconda delle dimensioni del progetto. Il compilatore TypeScript supporta la compilazione incrementale ( --watch compilatore --watch ), in modo che tutte le modifiche successive possano essere compilate a una maggiore velocità.

Il compilatore TypeScript può incorporare informazioni sulla mappa di origine nei file .js generati o creare file .map separati. Le informazioni sulla mappa di origine possono essere utilizzate dal debug di utilità come Chrome DevTools e altri IDE per correlare le righe nel JavaScript con quelle che le hanno generate in TypeScript. Ciò consente di impostare punti di interruzione e ispezionare le variabili durante il runtime direttamente sul codice TypeScript. Le informazioni sulla mappa di origine funzionano abbastanza bene, era molto prima di TypeScript, ma il debugging di TypeScript non è generalmente ottimo come quando si utilizza JavaScript direttamente. Prendi this parola chiave per esempio. A causa della semantica modificata della parola chiave intorno alle chiusure dal ES2015, this potrebbe effettivamente esistere durante il runtime come una variabile chiamata _this (vedere questa risposta ). Questo potrebbe confondervi durante il debug, ma generalmente non è un problema se ne siete a conoscenza o ispezionate il codice JavaScript. Va notato che Babel soffre esattamente lo stesso tipo di problema.

Ci sono alcuni altri trucchi che il compilatore TypeScript può fare, come generare codice di intercettazione basato su decoratori , generare codice di caricamento del modulo per diversi sistemi di moduli e analizzare JSX . Tuttavia, sarà probabilmente necessario uno strumento di compilazione oltre al compilatore Typescript. Ad esempio se vuoi comprimere il tuo codice dovrai aggiungere altri strumenti al tuo processo di compilazione per farlo.

Sono disponibili plug-in di compilazione TypeScript per Webpack , Gulp , Grunt e praticamente qualsiasi altro strumento di creazione JavaScript. La documentazione di TypeScript ha una sezione sull’integrazione con gli strumenti di costruzione che li riguardano tutti. Un linter è anche disponibile nel caso in cui si desideri un ulteriore controllo del tempo di costruzione. Ci sono anche un gran numero di progetti seme che ti faranno iniziare con TypeScript in combinazione con una serie di altre tecnologie come Angular 2, React, Ember, SystemJs, WebPack, Gulp, ecc.

Interoperabilità JavaScript

Poiché TypeScript è così strettamente correlato a JavaScript, ha grandi capacità di interoperabilità, ma alcuni lavori extra sono necessari per lavorare con le librerie JavaScript in TypeScript. Le definizioni TypeScript sono necessarie affinché il compilatore TypeScript capisca che le chiamate di funzioni come _.groupBy o angular.copy o $.fadeOut non sono in realtà dichiarazioni illegali. Le definizioni per queste funzioni sono collocate nei file .d.ts .

La forma più semplice che una definizione può assumere è quella di consentire l’uso di un identificatore in qualsiasi modo. Ad esempio, quando si usa Lodash , un file di definizione di una singola riga declare var _ : any consente di chiamare qualsiasi funzione desiderata su _ , ma ovviamente si è anche in grado di commettere errori: _.foobar() sarebbe un chiamata TypeScript legale, ma è ovviamente una chiamata illegale in fase di esecuzione. Se si desidera il supporto del tipo corretto e il completamento del codice, il file di definizione deve essere più preciso (vedere le definizioni di lodash per un esempio).

I moduli NPM che vengono preconfezionati con le proprie definizioni di tipo vengono compresi automaticamente dal compilatore TypeScript (consultare la documentazione ). Per quasi tutte le altre librerie JavaScript semi-popolari che non includono le proprie definizioni, qualcuno ha già reso disponibili definizioni di tipo attraverso un altro modulo npm. Questi moduli hanno come prefisso “@ types /” e provengono da un repository Github chiamato DefinitelyTyped .

C’è un avvertimento: le definizioni del tipo devono corrispondere alla versione della libreria che si sta utilizzando in fase di esecuzione. In caso contrario, TypeScript potrebbe non consentire all’utente di chiamare una funzione o dereferenziare una variabile esistente o consentire di chiamare una funzione o una dereferenza una variabile che non esiste, semplicemente perché i tipi non corrispondono al tempo di esecuzione in fase di compilazione . Quindi assicurati di caricare la versione corretta delle definizioni di tipo per la versione corretta della libreria che stai utilizzando.

Per essere onesti, c’è un po ‘di fastidio a questo e potrebbe essere uno dei motivi per cui non si sceglie TypeScript, ma invece si usa qualcosa come Babel che non soffre affatto di dover ottenere le definizioni del tipo. D’altra parte, se sai cosa stai facendo, puoi facilmente superare qualsiasi tipo di problema causato da file di definizione errati o mancanti.

Conversione da JavaScript a TypeScript

Qualsiasi file .js può essere rinominato in un file .ts ed eseguito attraverso il compilatore TypeScript per ottenere sintatticamente lo stesso codice JavaScript di un output (se era sintatticamente corretto in primo luogo). Anche quando il compilatore TypeScript riceve errori di compilazione, produrrà comunque un file .js . Può anche accettare file .js come input con il flag --allowJs . Questo ti permette di iniziare subito con TypeScript. Sfortunatamente gli errori di compilazione potrebbero verificarsi all’inizio. Uno ha bisogno di ricordare che questi non sono errori di show-stop come si può essere abituati con altri compilatori.

Gli errori di compilazione che si ottengono all’inizio quando la conversione di un progetto JavaScript in un progetto TypeScript sono inevitabili per la natura di TypeScript. TypeScript controlla tutto il codice per validità e quindi ha bisogno di conoscere tutte le funzioni e le variabili che vengono utilizzate. Pertanto è necessario che siano presenti definizioni di tipo per tutti, altrimenti è probabile che si verifichino errori di compilazione. Come menzionato nel capitolo precedente, per quasi tutti i framework JavaScript ci sono file .d.ts che possono essere facilmente acquisiti con l’installazione di pacchetti DefinitelyTyped . Potrebbe tuttavia essere che tu abbia utilizzato una libreria oscura per cui non sono disponibili definizioni TypeScript o che hai caricato in polyfilled alcune primitive JavaScript. In tal caso è necessario fornire definizioni di tipo per questi bit in modo che gli errori di compilazione scompaiano. Basta creare un file .d.ts e includerlo nell’array dei files di tsconfig.json, in modo che venga sempre considerato dal compilatore TypeScript. In esso dichiarano quei bit di cui TypeScript non sa di tipo any . Una volta eliminati tutti gli errori, è ansible introdurre gradualmente la digitazione su tali parti in base alle proprie esigenze.

Saranno necessari anche alcuni lavori per (ri) configurare la pipeline di costruzione per ottenere TypeScript nella pipeline di build. Come menzionato nel capitolo sulla compilazione, ci sono un sacco di buone risorse là fuori e ti incoraggio a cercare progetti seme che usano la combinazione di strumenti con cui vuoi lavorare.

Il più big ostacolo è la curva di apprendimento. Ti incoraggio a giocare con un piccolo progetto all’inizio. Guarda come funziona, come costruisce, quali file utilizza, come è configurato, come funziona nel tuo IDE, come è strutturato, quali strumenti usa, ecc. Convertire una grande base di codice JavaScript in TypeScript è molto fattibile quando sai cosa stai facendo, ma potrebbe essere frustrante quando non lo fai.

Adozione

TypeScript è open source (concesso in licenza Apache 2, vedi github ) e supportato da Microsoft. Anders Hejlsberg , l’architetto principale di C # sta guidando il progetto. È un progetto molto attivo; il team di TypeScript ha rilasciato molte nuove funzionalità negli ultimi anni e molte di quelle grandi sono ancora in programma a venire (vedi la roadmap ).

Nel sondaggio sugli sviluppatori di StackOverflow 2017, TypeScript è stato il più popolare tra i traspiler JavaScript (il 9 ° posto assoluto) e si è aggiudicato il terzo posto nella categoria delle lingue di programmazione più amate.

TypeScript fa qualcosa di simile a ciò che less o sass fa per CSS. Sono super set di esso, il che significa che ogni codice JS che scrivi è un codice TypeScript valido. In più puoi usare le altre chicche che aggiunge alla lingua, e il codice transpiled sarà js valido. È anche ansible impostare la versione JS su cui si desidera inserire il codice risultante.

Attualmente TypeScript è un super set di ES2015, quindi potrebbe essere una buona scelta per iniziare ad apprendere le nuove funzionalità di js e traspare allo standard necessario per il tuo progetto.

Fondamenti di tipoScript” – un video-corso di Pluralsight di Dan Wahlin e John Papa è un ottimo, attualmente (25 marzo 2016) aggiornato per riflettere TypeScript 1.8, introduzione a Typescript.

Per me le funzioni davvero buone, oltre alle buone possibilità per intellisense, sono le classi , le interfacce , i moduli , la facilità di implementazione di AMD e la possibilità di utilizzare il debugger di Visual Studio Typescript quando viene richiamato con IE.

Riassumendo : Se usato come previsto, Typescript può rendere la programmazione JavaScript più affidabile e più facile. Può aumentare significativamente la produttività del programmatore JavaScript sull’intero SDLC.

Ecma script 5 (ES5) supportato da tutti i browser e precompilato. ES6 / ES2015 e ES / 2016 sono arrivati ​​quest’anno con un sacco di cambiamenti, quindi per far apparire questi cambiamenti c’è qualcosa nel mezzo che dovrebbe preoccuparsi di questo tipo. • TypeScript è Tipi -> Significa che dobbiamo definire il tipo di dati di ciascuna proprietà e metodi. Se conosci C #, allora Typescript è facile da capire. • Il grande vantaggio di TypeScript è rappresentato dai problemi relativi al tipo di id quadro prima della produzione. Ciò consente di fallire i test di unità in caso di mancata corrispondenza di tipo.