Gennaio 2017

Volume 32 Numero 1

Il presente articolo è stato tradotto automaticamente.

The Working Programmer - Come usare MEAN: Creare script con TypeScript

Da Ted Neward | Gennaio 2017

Ted NewardBentornato, MEANers.

In questa serie in Media avanzamento tramite l'ultimo anno e mezzo, una delle modifiche interessante per l'elenco di argomenti è stata alla parte "A" del nome della serie: AngularJS effettuato un commutatore principali rilasciando formalmente versione 2 della relativa riga e con quello fornito alcune complete (e) modifiche importanti al framework. Una delle modifiche più importante è la scelta di adottare macchina come AngularJS "lingua preferita" per la creazione di applicazioni AngularJS 2, invece, semplicemente ECMAScript per la riga 1. x.

Molti lettori hanno familiari con TypeScript, naturalmente, perché è il linguaggio più recente a emergere dai fiori codice Redmond. Per coloro che non hanno familiarità con TypeScript, rest semplici, è effettivamente simile alla sintassi ECMAScript 2015 è detto in precedenza in questa serie, con un po' più mediante le informazioni sul tipo di macchina. I lettori che desiderano un approfondimento completa nel linguaggio sono invitati a leggere l'articolo di Peter Vogel, "Informazioni su TypeScript," nel numero di gennaio 2015 di MSDN Magazine (msdn.com/magazine/dn890374).

Tuttavia, AngularJS 2 utilizza un particolare sottoinsieme delle funzionalità di macchina e, inoltre, non tutti i lettori sono completamente dimestichezza con la sintassi macchina ancora. Inoltre, TypeScript ha subito alcune modifiche dall'articolo del Vogel è stato scritto (versione 2 rilasciata nel mese di settembre 2015 tardiva). Pertanto, si desidera eseguire un passaggio rapido tramite il linguaggio per assicurarsi di che trovarsi nella stessa pagina prima di indirizzamento AngularJS 2.

Pertanto, è opportuno analizzare alcune macchina.

Aggiunta di "Type" a "Script"

Concettualmente, TypeScript è un concetto semplice: Richiedere la sintassi tradizionale di ECMAScript e aggiungere alcune informazioni (facoltativo) digitare sotto forma di annotazioni del tipo, simile a come F # e altri linguaggi funzionali forniscono dichiarazioni di tipo. Il compilatore macchina (tecnicamente denominato un "transpiler" perché diventa origine-origine, il codice ECMAScript insito nel processo di produzione) verifica che tutte le informazioni di tipo vengano rispettate e osservate; ma il risultato è comunque buone JavaScript precedente, tipizzati in modo dinamico, di facile integrazione con i browser. In altre parole, l'obiettivo è ottenere tutti i vantaggi di un linguaggio indipendente dai tipi, ad esempio c# (riduzione degli errori di codice ovvio tramite verifica statica) entrambi senza cambiare la piattaforma di browser JavaScript sottostante (buona fortuna con!) o compilare un platform-on-top-of-another-platform costosa. Perché uno dei principi fondamentali della macchina che "qualsiasi persona ECMAScript programma è inoltre legali macchina", l'adozione macchina può essere una festa incrementale. Richiedere graduali small, recupero cozy con le nuove funzionalità solo in quanto il team abbia dimestichezza in tal modo, invece di passare interamente con la nuova sintassi (ad esempio quali uno potrebbe essere necessario effettuare con un linguaggio transpiled completamente nuova, ad esempio CoffeeScript, Fantom o ClojureScript).

È in tale spirito di quest'ultimo all'inizio di questo jaunt in TypeScript. Verrà incentrata sulle funzionalità che AngularJS 2 utilizza la maggior parte dei o più evidente e lasciare il resto per ulteriori approfondimenti lungo la strada.

L'installazione di TypeScript

La prima cosa da notare è che, come pacchetti più basati su Node. js, TypeScript è un pacchetto npm. Pertanto, si installa macchina tramite il normale comando "npm install":

npm install –g typescript

Poiché TypeScript installerà un comando globale "tsc ("), è importante utilizzare "-g," il flag "globale", durante l'installazione di TypeScript. Soffermarsi e accertarsi che è stato completamente installato lo strumento da riga di comando eseguendo "tsc":

$ tsc --version
Version 2.0.3

Pertanto, con TypeScript installato, il passaggio successivo consiste nello scrivere codice macchina.

Moduli

Il punto di partenza per la discussione è che i moduli di TypeScript.

Presuppongono che si crea un file, person.ts, che deve per contenere un componente. (Il termine "componente" non è uno che mette in evidenza TypeScript, ma non AngularJS 2.) Il primo passaggio consiste nel creare una funzione semplice che può essere richiamato da un altro file, pertanto è necessario prima creare tale funzione:

function sayHello(message: string) {
  console.log("Person component says", message);
}

Si noti l'annotazione di tipo per il parametro, assicurarsi che il singolo parametro deve essere una stringa. Questa è la base della macchina e garantisce che solo le stringhe possono essere passate come parametri. Concesso, un componente semplice grazie a questa funzione per sé, ma semplici o complessi, deve essere utilizzato per essere utile.

Quindi, utilizziamo il: un'applicazione macchina può utilizzare un componente tramite un'istruzione di importazione, come illustrato di seguito:

import { sayHello } from './person';
sayHello("Fred");

In pratica, l'istruzione "import" dichiara che si sta utilizzando l'elemento denominato "sayHello" dal modulo "person". (Sono presenti altre forme di sintassi di importazione che si vedrà in seguito). Quindi, eseguire i due file, il suddetto person.ts e app.ts questo codice, tramite il compilatore tsc:

tsc person.ts app.ts

Sfortunatamente, accetterà TypeScript, indicante che person.ts non è un modulo.

I moduli sono, in termini gergali macchina, il costrutto di linguaggio che fornisce una "casella" attorno un raggruppamento strettamente del codice. Come è scritto, person.ts sarebbe facilmente utilizzabile come modulo in scenari di JavaScript precedenti. semplicemente definendo una funzione in un file e il riferimento a tale file inserisce la funzione in ambito globale. Tuttavia, TypeScript richiede una sintassi più esplicita, è necessario utilizzare la parola chiave di esportazione per dichiarare che cos'è parte dell'area della superficie esterna del componente, come illustrato di seguito:

export function sayHello(message: string) {
  console.log("Person component says", message);
}

Macchina, i file con un livello superiore di importazione o esportazione istruzione viene considerato un modulo, in modo semplice dichiarazione che questa funzione viene esportato in modo implicito definisce tutti person.ts da un modulo.

Una volta modificata, macchina è felice e due nuovi file, person.js e js, posizionare nel file System, in attesa di essere utilizzato.

Aggiunta di classe

TypeScript, simile al linguaggio ECMAScript 2015 su cui è basato in grado di comprendere il concetto di base delle classi, ha senso definire persona come una classe da utilizzare, come illustrato nella figura 1.

Figura 1 persona semplice classe

export class Person {
  firstName: string;
  lastName: string;
  constructor(fn: string, ln: string) {
    this.firstName = fn;
    this.lastName = ln;
  }
  greet() : string {
    return this.fullName + " says hello!";
  }
  get fullName() : string {
    return this.firstName + " " + this.lastName;
  }
}

Questo è tutto relativamente semplice individuare, anche per gli utenti non siano presenti macchina prima. La parola chiave esportazione nuovamente indica che questa classe è destinata di fuori di questo modulo. I campi firstName e lastName utilizzare annotazioni TypeScript per ottenere il compilatore potrà imporre "stringa-ness", il metodo greet restituisce una stringa per i chiamanti e il metodo fullName è dichiarata come una funzione di accesso sintetico proprietà di sola lettura, costituito da campi firstName e lastName. L'utilizzo del tipo Person nel file app.ts è piuttosto semplice: è sufficiente importare il file person.ts del tipo Person e ne crea uno utilizzando la parola chiave nuova:

import { Person } from './Person';
let ted = new Person("Ted", "Neward");
console.log(ted.greet());

Attenzione lettori si noterà che la riga di importazione è stata modificata, anziché eseguire il pull in sayHello, estrae il tipo di persona. Sebbene sia certamente possibile elencare tutti i simboli esportati dal vivo tra le parentesi dell'istruzione di importazione, che sarebbe noioso veramente molto rapidamente. TypeScript fornisce una funzionalità di importazione con caratteri jolly, ma non si desidera che esportare tutti i del modulo nomi per eseguire solo lo spazio dei nomi globale, è necessario fornire un nome con cui tutti i nomi saranno visibili. Utilizzarlo leggermente modificherebbe il codice dell'applicazione:

import * as PerMod from './Person';
let ted = new PerMod.Person("Ted", "Neward");
console.log(ted.greet());

Ovviamente, questo non è un codice di qualità, perché PerMod è un nome terribile.

Interfaccia macchina

Naturalmente, un obiettivo più diffusi per lo sviluppo basato su componenti (ovvero, tenere presente che, per le quali AngularJS 2) è che deve essere una chiara separazione tra come gli utenti di un componente di utilizzano il componente e come il componente fornisce questa utilità, in altre parole, la distinzione tra "interfaccia e implementazione". TypeScript richiede una pagina dal relativo pari livello concettuale in c#, fornendo la possibilità di dichiarare le interfacce, quali, ad esempio in c#, sono le promesse di comportamento che fornisce un'implementazione.

Se il componente di persona deve distinguere tra tipi diversi di persone senza restrizioni di implementazione, è possibile definire persona come un'interfaccia, fornire diverse implementazioni e forse un costruttore di funzione per rendere più semplice costruire le persone senza doversi preoccupare di informazioni tra di essi, come illustrato nella figura 2.

Figura 2 Creazione di una persona

export function createPerson(
  firstName: string, lastName: string, occupation: string) : Person {
  if (occupation == "Programmer")
    return new Programmer(firstName, lastName);
  else if (occupation == "Manager")
    return new Manager(firstName, lastName);
  else
    return new NormalPerson(firstName, lastName);
}
export interface Person {
  firstName: string;
  lastName: string;
  greet() : string;
  fullName: string;
}

Creazione di una classe che implementa l'utente è semplice, utilizzando la parola chiave implements, come illustrato in figura 3.

Figura 3 un'implementazione di persona

class NormalPerson implements Person {
  firstName: string;
  lastName: string;
  constructor(fn: string, ln: string) {
    this.firstName = fn;
    this.lastName = ln;
  }
  greet() : string {
    return this.fullName + " says hello!";
  }
  get fullName() : string {
    return this.firstName + " " + this.lastName;
  }
}

E, come illustrato nella figura 4, la creazione di sottotipi di NormalPerson (per i gestori e i programmatori) è ugualmente semplice, la creazione di un costruttore che rinvia alla relativa classe padre e quindi si esegue l'override del metodo greet per restituire messaggi appropriate per ogni attività.

Figura 4 programmatore implementazione

class Programmer extends NormalPerson {
  constructor(fn: string, ln: string) {
    super(fn, ln);
  }
  greet() : string {
    return this.fullName + " says Hello, World!";
  }
}
class Manager extends NormalPerson {
  constructor(fn: string, ln: string) {
    super(fn, ln);
  }
  greet() : string {
    return this.fullName + " says let's dialogue about common synergies!";
  }
}

Nuovamente, a parte i descrittori di tipo e la dichiarazione dell'interfaccia stessa, questo è simile al diritto sintassi 2015 ECMAScript, ma grazie a TypeScript il controllo del tipo, qualsiasi tentativo di utilizzare un valore diverso da una stringa come verranno rifiutati correttamente i parametri ai costruttori. Si noti tuttavia che il fatto che le classi esportate non indica che il codice del client è chiaro che cos'è l'implementazione effettiva; tutti i client sa che l'interfaccia utente definisce tre proprietà, firstName, lastName e fullName e un metodo, greet, che il client può utilizzare.

Effetti

L'ultima funzionalità ovvia della macchina che richiede una spiegazione è elementi Decorator, una funzionalità sperimentale per ECMAScript (e TypeScript, d'altra parte) massima simile attributi personalizzati, ma si comportano in modo molto diverso. Essenzialmente, utilizzando una notazione @ con prefisso, è possibile definire una funzione che verrà richiamata ogni volta che vengono richiamati i costrutti di codice diversi, ovvero quando viene costruita una classe, quando viene richiamato un metodo, quando le proprietà sono accessibili (o modificate), o anche quando i parametri vengono passati come parte di una chiamata al metodo o funzione. È ovvio tentativo di fornire alcuni approcci di programmazione orientata ad aspetti a TypeScript e AngularJS 2 sfrutta abbastanza frequentemente.

L'esempio classico di una libreria di programmazione orientata ad aspetti è quello di registrazione chiamate di funzione; si desidera riutilizzare il codice che accede alla console ogni volta che una determinata funzione o metodo viene chiamato, indipendentemente da dove che chiamano proviene. Questa operazione, per definizione, è una questione trasversale, un blocco di codice che definisce i costrutti di riutilizzo tradizionale orientata agli oggetti, ad esempio ereditarietà. Usa TypeScript, è possibile scrivere un elemento decorator log e applicare tale elemento decorator per i metodi che si desidera decorare con il comportamento di registrazione. Tale comportamento viene richiamato ogni volta che viene richiamato il metodo decorato.

In pratica, ciò significa che se si scrive un elemento decorator log, l'implementazione di persona restituito può utilizzare @log sul metodo greet e chiamate verranno registrati console, come illustrato di seguito:

import log from './log';
// ... Code as before
class Manager extends NormalPerson {
  constructor(fn: string, ln: string) {
    super(fn, ln);
  }
  @log()
  greet() : string {
    return this.fullName + " says let's dialogue about common synergies!";
  }
}

Quando si esegue, produce alcuni interessante registrazione a livello di metodo seguente:

$ node app.js
Call: greet() => "Ted Neward says Hello, World!"
Ted Neward says Hello, World!
Call: greet() => "Andy Lientz says let's dialogue about common synergies!"
Andy Lientz says let's dialogue about common synergies!
Call: greet() => "Charlotte Neward says hello!"
Charlotte Neward says hello!

Il componente log è un po' ingegnosa di tipo runtime-mongery, ma un po' esula dall'ambito di questa colonna. È incluso in figura 5 per l'analisi, ma non verranno descritte come funziona in questo caso diverso per indicare che macchina in modo efficace inserirà il codice in posizioni appropriate per effettuare chiamate alla funzione che restituisce l'elemento decorator log.

Figura 5, che definisce l'annotazione di registrazione

export default function log() {
  return function(target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor)
  {
    // Save a reference to the original method
    var originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {
      var argsLog = args.map(a => JSON.stringify(a)).join();
      var result = originalMethod.apply(this, args);
      var resultLog = JSON.stringify(result);
      console.log(`Call: ${propertyKey}(${argsLog}) => ${resultLog}`);
      return result;
    }
    // Return edited descriptor instead of overwriting
    // the descriptor by returning a new descriptor
    return descriptor;
  }
}

Il sito Web di TypeScript descrive gli elementi Decorator a bit.ly/2fh1lzC, per coloro che desiderano sapere come crearli. Fortunatamente, che consente di creare propri elementi Decorator non è necessaria per utilizzare 2 AngularJS in modo efficiente; Tuttavia, sapere come utilizzare gli elementi Decorator già esistenti è certamente un requisito. Per i principianti, AngularJS 2 li utilizza per l'inserimento delle dipendenze, base dei componenti di base di "The angolare Way" fin dal principio.

Conclusioni

Ho adottato un passaggio rapido tramite TypeScript e anche se non è certamente un trattamento completo, otterrà avrete una volta prelevati 2 AngularJS e avviare pirateria su di esso. Si noti che alcune delle funzionalità descritte di seguito richiede le opzioni del compilatore particolare; in particolare, gli elementi Decorator, richiederanno l'opzione del compilatore: experimentalDecorators (o equivalente in tscconfig.json). La maggior parte dei casi, tuttavia, lo scaffolding generato Yeoman hanno a disposizione le opzioni destra già e 2 AngularJS gli sviluppatori non devono preoccuparsi di essi.

Proposito, è possibile iniziare a esplorare AngularJS, componenti e i modelli e le viste, AH mia!, Ecco quindi backup nel docket. Fino a quando quindi, buona codifica!


Ted Newardè un consulente polytechnology basato su Seattle, relatore e mentore.  Egli ha scritto oltre 100 articoli, è un #MVP F, ha creato e coautore di numerosi libri. Contattarlo all'indirizzo ted@tedneward.com se si è interessati a far lui provenire collaborano con il team o leggere il suo blog all'indirizzo blogs.tedneward.com.

Grazie al seguente esperto tecnico per la revisione dell'articolo: Shawn Wildermuth