Introducción A Typescript
Introducción A Typescript
Introducción A Typescript
of Contents
Introduccin
1.1
1.1.1
1.1.2
Tipos de datos
1.2
Tipos primitivos
1.2.1
Tuple / Tuplas
1.2.2
Enum
1.2.3
Any
1.2.4
Void
1.2.5
Let
1.2.6
Const
1.2.7
For in
1.2.8
For of
1.2.9
Funciones
1.2.10
Genricos
1.2.11
Type Alias
1.2.12
Type Union
1.2.13
Type Guards
1.2.14
Desestructuracin
1.3
Estructuracin
1.4
Promesas
1.5
Generators
1.6
1.7
Clases
1.8
Mdulos
1.9
Sistemas de automatizacin
1.10
Consejos
1.11
1.11.1
Clases estticas
1.11.2
1.11.3
Quines somos?
1.12
Introduccin
Licencia
Este obra est bajo una licencia de Creative Commons Reconocimiento-NoComercialSinObraDerivada 4.0 Internacional.
Descargas
PDF
EPUB
MOBI
URL Base
Introduccin
TypeScript es un lenguaje de programacin moderno que permite crear aplicaciones web
robustas en JavaScript. TypeScript no requiere de ningn tipo de plugin, puesto que lo que
hace es generar cdigo JavaScript que se ejecuta en cualquier navegador, plataforma o
sistema operativo.
TypeScript es un "transpilador", es decir, un compilador que se encarga de traducir las
instrucciones de un lenguaje a otro, aqui lo llamaremos tambin pre-compilador ya que este
realmente intenta realizar las funciones de un compilandor ms las funciones de un
traductor de instrucciones.
TypeScript es un lenguaje pre-compilado, es decir, un lenguaje el cual ser compilado
finalmente a javascript, la versin del javascript en la cual ser compilado junto con otras
configuraciones estar en el archivo tsconfig, TypeScript nos proporciona una serie de
ventajas sobre javascript, o ES2016,.., ya que tiene una serie de caracteristicas que ES* no
suele tener, como por ejemplo:
Interfaces
Clases (Clases de verdad)
Es furtemente tipado
Introduccin
Si nos dice la versin de NodeJS que tenemos proseguiremos con el siguiente paso la
descarga de TypeScript para ello abriremos una terminal y escribiremos esto
(Windows\/Linux\/Mac)
npm install -g typescript
Con este comando generaremos el archivo de configuracin bsico que utilizar TypeScript
para compilar la informacin.
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false
},
"exclude": [
"node_modules"
]
}
La presencia de este archivo significa que este directorio es la raz del proyecto.
Para que se compile un fichero TypeScripte tienes que utilizar el siguiente comando
tsc -w
Si al realizar esta instalacin ocurre algn error, una alternativa para practicar sera la
pgina de pruebas de TypeScript
Buscador
Para buscar en todos los ficheros de un proyecto utilizamos ctrl + alt + t
Debuggin
Para poder debuggear en Visual Code ts, necesitamos configurar el archivo de
configuracin tsconfig y en la lnea sourceMap la ponemos a true dejando el fichero de
configuracin de la siguiente forma:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": true
},
"exclude": [
"node_modules"
]
}
Una vez modificada esa lnea se generar un archivo .map con el mismo nombre del
archivo .ts que tengamos en ese archivo .map estarn asociadas las lneas del archivo
.js compilado y la lnea del archivo .ts una vez modificado, pondremos el punto de
"cwd": "${workspaceRoot}",
"preLaunchTask": null,
"runtimeExecutable": null,
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "development"
},
"externalConsole": false,
"sourceMaps": true,
"outDir": null
},
{
"name": "Asociar",
"type": "node",
"request": "attach",
"port": 5858,
"address": "localhost",
"restart": false,
"sourceMaps": false,
"outDir": null,
"localRoot": "${workspaceRoot}",
"remoteRoot": null
},
{
"name": "Attach to Process",
10
"type": "node",
"request": "attach",
"processId": "${command.PickProcess}",
"port": 5858,
"sourceMaps": false,
"outDir": null
}
]
}
Para debuggear al siguiente punto de debug utilizamos el botn F10 y para un paso ms
controlado un F11
11
Tipos de datos
Tipos de datos
TypeScript es un lenguaje que aade a JavaScript una capa de tipado esttico y algunas
otras incorporaciones de OOP tradicional. Esta capa puede resultarnos de muchsima
ayuda durante el desarrollo. Sin embargo, todas estas caractersticas son simplemente para
ayudar a trabajar con JavaScript en tiempo de diseo, ya que TypeScript compila todo
como JavaScript tradicional.
Tipado esttico o fuertemente tipado: Se debe de definir el tipo de dato, obligando a que no
pueda haber errores con los tipos de datos
Tipado dinmico o dbilmente tipado: No se deben de o tiene porque especificar el tipo de
dato (PHP, Javascript)
Porque typescript es fuertemente tipado
var a=3;
var b="hola";
var c=a+b; // Resultado 3hola
if ("0" == 0) // es true
if ("3" === 3) // es false
Estos ejemplos son posibles problemas que tienen los lenguajes dbilmente tipadas
12
Tipos primitivos
Tipos primitivos
Boolean
true o false
let isDone: boolean = false;
Number
Datos nmericos
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744
String
Cadenas de caracteres y/o textos
let color: string = "blue"; //
color = 'red';
Tambin se pueben utilizar "Templates" plantillas para concatenar strings como por ejemplo:
let fullName: string = `Bob Bobbington`;
let age: number = 37;
let sentence: string = `Hello, my name is ${ fullName }. I'll be ${ age + 1 } years ol
d next month.`
Para poder utilizar esta sintaxis los string deben estar contenidos entre ` .
Este tipo de sintaxis es el equivalente a:
let sentence: string = "Hello, my name is " + fullName + "." + "I'll be " + (age + 1)
+ " years old next month."
13
Tipos primitivos
Plantillas de strings
Las plantillas de strings se escriben entre ` y la sintxis sera:
var lyrics = 'Never gonna give you up'; // entre comillas simples
var html = `<div>${lyrics}</div>`; // entre tilde inversa
Este tipo de plantillas permite que podamos utilizar ms de una lnea sin tener que utilizar el
operador + por eso se dice que un "string templated" es multilineal
La variable que acabamos de crear nada ms que podr contener el valor que le hemos
asignado, es decir 'Hola'.
let literalString = 'Hello';
literalString = 'Bye'; // Error: "Bye" is not assignable to type "Hello"
Por si solo no tiene una gran utilidad por lo que se combina con union types, type guards, y
type alias. Los cuales explicaremos ms tarde.
type CardinalDirection =
"North"
| "East"
| "South"
| "West";
function move(distance: number, direction: CardinalDirection) {
// ...
}
move(1,"North"); // Okay
move(1,"Nurth"); // Error!
Array
Arrays, sino se les especifica tipo son ANY
let list: number[] = [1, 2, 3];
14
Tipos primitivos
Con esta sintaxis se puede especificar qu tipo de datos debe haber en el array
let list: Array<number> = [1, 2, 3];
Null
Es cuando un objeto o variable no esta accesible.
Undefined
Es cuando un objeto o variabe existe pero no tiene un valor. Si nuestro cdigo interactua
con alguna API podemos recibir null como respuesta, para evaluar esas respuestas es
mejor utilizar == en vez de ===
// ----- ejemplo.ts ----------console.log(undefined == undefined); // true
console.log(null == undefined); // true
console.log(0 == undefined); // false
console.log('' == undefined); // false
console.log(false == undefined); // false
15
Tuple / Tuplas
Tuple / Tuplas
Como en base de datos, hacen referencia a registros clave / valor
// Declaracin de tublas
let x: [string, number];
// Inicializacin correcta
x = ["hello", 10]; // OK
// Inicializacin incorrecta
x = [10, "hello"]; // Error
Para acceder a los datos dentro de las tuplas de las cuales sabes el ndice se hace as:
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, Un tipo 'number' no tiene la funcin 'substr'
16
Enum
Enum
Los enumerado en TypeScript, son distintos a los enumerados de otros lenguajes de
programacin, estos solo almacenan nmeros para identificar las constantes.
Si no se le especifica el valor por defecto se lo asigna normalmente, tambin es importante
saber, que los enumerados no aceptan que su valor sea un String, solamente nmero
enum Direction {
Up = 1, // Si se le asigna un valor numerico primero, los siguientes valores empi
ezan desde el nmero especificado
Down = NaN, // Si le ponemos un NaN despes de haber inicializado un valor nos ob
liga a inicializar el siguiente desus de este, esto no solo pasa con Nan, pasa con St
ring.length, etc.
Left = "asdasd".length,
Right = 1 << 1 // Tambin admiten operadores binarios
}
var a = Direction.Up;
console.log(Direction.Down);
Es muy importante saber que distintos enumerados no pueden ser comparados ya que el
nombre de los enumerados no es el mimo, aunque puedan tener el mismo indice nmerico.
17
Enum
18
Any
Any
Puede ser cualquier tipo de objeto de javascript
let notSure: any = 4;
notSure = "maybe a string instead"; // typeof = string
notSure = false;; // typeof = boolean
19
Void
Void
function warnUser(): void {
alert("This is my warning message");
}
Este tipo de dato no es recomendable para variables ya que solo pueden ser asignados
valores null o undefined
let unusable: void = undefined;
20
Let
Let
En javascript hay dos formas de declarar variables: var y let , var no tiene un mbito
de bloque mientras que let s.
var
var foo = 123;
if (true) {
var foo = 456;
}
console.log(foo); // 456
let
let foo = 123;
if (true) {
let foo = 456;
}
console.log(foo); // 123
21
Const
Const
Ha sido aadido en ES6 / TypeScript permitiendonos aadir variables inmutables tanbien
conocidas como constantes. El uso de const es una buena prctica de mantenimiento y
legibilidad.Las constantes deben ser declaradas y asignadas siempre.
const foo = 123;
foo = 456; // NO permitido
Pero si se puede modificar el contenido de las variables que contiene el objeto literal,
ejemplo:
const foo = { bar: 123 };
foo.bar = 456; // Permitido
console.log(foo); // { bar: 456 }
22
For in
For in
For in es una caracterstica que ya tenia javascript ,y no ha sido mejorada en TypeScript,
mediante la cual puedes acceder y recorrer objetos y arrays y obtener tanto los ndices
como los valores.
For in accediendo al valor de una variable dentro de un objeto:
TypeScript
let list = {a: 1, b: 2, c:3};
for(let i in list){
console.log(list[i]); // 1, 2, 3
}
Javascript
var list = { a: 1, b: 2, c: 3 };
for (var i in list) {
console.log(list[i]); // 1, 2, 3
}
Javascript
var list = { a: 1, b: 2, c: 3 };
for (var i in list) {
console.log(i); // a, b, c
}
23
For in
24
For of
For of
For of es una caracterstica nueva de ES6 con la cual puedes acceder y recorrer arrays y
strings obteniendo su valor, es decir, no puede recorrer objetos. Aunque se podran
recorrer objetos en el caso de que estos fueran creados por clases que implementen
Symbol.iterator . for ... of tambin tiene un peor rendimiento en comparacin con el
for...in ya que al compilarlo a JS crea ms variables y hace ms comprobaciones.
Javascript
var list = ["a", "b", "c"];
for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
var b = list_1[_i];
console.log(b); // a, b, c
}
Javascript
25
For of
For of accediendo al valor de una variable dentro de un objeto, el cual nos dar error:
TypeScript
let obj = {a: 1, b: 2, c:3};
for(let i of obj){
console.log(i); // Error
}
Javascript
var obj = { a: 1, b: 2, c: 3 };
for (var _i = 0, obj_1 = obj; _i < obj_1.length; _i++) {
var i = obj_1[_i];
console.log(i); // Error
}
26
Funciones
Funciones
Este tipo de funcin hace referencia al objeto que llama a esta funcin
setTimeOut(function(){
console.log(this); // Elemento Que llama a la funcin
}, 2000);
Este tipo de funciones, lo que hacen es que el this no hace referencia al padre sino al objeto
que contiene la funcin
setTimeOut(() => {
console.log(this);// Elemento que contiene esta funcin
},2000);
Ejemplos sobre como evitar el tipo Any y filtrar solo por los tipos de datos que necesitamos
// para poder definir tipos utilizaremos el O lgico
function padLeft(value: string, padding: string | number) {
if(typeof padding === "number"){
return Array(padding + 1).join(" ") + value;
}
if(typeof padding === "string") {
return Array(padding.length + 1).join(" ") + value;
}
// Si existiera Any tendriamos que controlar la excepcin
// Como buenas practicas y ya que este cdigo al fin y al cabo
// ser javascript y es vulnerable a inyecin siempre est bien
// realizar el control de las posibles excepciones
throw new Error(`Expected String or number, got '${padding}' `);
}
console.log(padLeft("hello", "aaa")); // Ejemplo de funcin con texto -> Funciona
console.log(padLeft("hello", 5)); // Ejemplo de funcin con nmero -> Funciona
console.log(padLeft("hello", true)); // Ejemplo de funcin con texto -> NO FUNCION
A (no compila)
27
Funciones
28
Genricos
Genricos
Los tipos genricos, son aquellos que como las interfaces no se vern compilados en
Javascript ya que solo estn accesibles en tiempo de compilacin, La manera adecuada de
realizar la sobrecarga de mtodos es con los tipos genricos un ejemplo sera as:
Versin TypeScript
function echo<T>(arg: T) : T {
return arg;
}
let a = echo<number>(1); // El typeof es Number
let b = echo<String>("Hola mundo"); // El typeof es String
La diferencia entre esta forma y la otra, es que de esta forma, podramos recibir cualquier
tipo de objeto, y no deberamos especificar el tipo de objeto que esperamos, esto esta muy
bien ya que est diseado para los objetos que no son primitivos de javascript. Con esto
evitamos el Any y mejorara la manera de realizar la sobrecarga (Lejos de como sera en
Java o C#).
Con los tipos genricos se debe tener cuidado, ya que no todos los mtodos estan
disponibles para todos lo tipos de objetos.
TypeScript
class Generic<T> {
add: (X: T, y:T) => T;
}
let myGeneric = new Generic<number>();
console.log(myGeneric.add = function (x,y) {return x + y});
console.log(myGeneric.add(3,4));
29
Genricos
Javascript
var Generic = (function () {
function Generic() {
}
return Generic;
}());
var myGeneric = new Generic();
console.log(myGeneric.add = function (x, y) { return x + y; });
console.log(myGeneric.add(3, 4));
Como se puede apreciar en este ejemplo podemos declarar una funcin dentro de una
clase que devolver lo que le pasemos por parametro, permitiendonos as modificar los
returns de nuestras funciones segn queramos.
Para poder pasar como parametro a una funcin y asegurarnos de que ese parmetro tiene
un mtodo en concreto deberemos implementar una interfaz y forzar al parmetro que se le
pasar a la funcin a utilizar dicha interfaz.
TypeScript Nota: Es muy importante que veas que cuando se implementa una interfaz
en un parmetro utilizamos la palabra reservada extends y no la palabra reservada
implements
// Interfaz que asegura que el parametro tenga el metodo length
interface withLength {
length: number;
}
// El parametro hereda de la interfaz la cual fuerza al parametro tenga el mtodo leng
th
function echo<T extends withLength>(arg: T): T {
console.log(arg.length);
return arg;
}
// Esto funcionar
let a = echo("aaa");
let t = echo({length: 2, name: "aa"});
// Esto NO funcionar
let b = echo(1);
Javascript
30
Genricos
Tambin podemos hacer que los atributos que intentamos modificar se encuentren dentro
del tipo de objeto que le pasa, eso sera de la siguiente forma.
function copyFields<T extends U, U>(source: T, target: U) : U {
for(let id in source){
if(target[id] != undefined){
source[id] = target[id];
}else {
target[id] = source[id];
}
}
return target;
}
let a = {a: 1, b: 2, c: 3};
let b = copyFields (a, {b: 10, c:20}); // Esto funcionar
let c = copyFields (a, {Q: 20}); // Esto NO funcionar
console.log(b); // 1, 10, 20
console.log(c); // Lo devuelve si lo compilas a pesar de saber que est mal
31
Type Alias
Type Alias
Los Type Alias son exactamente los mismos tipos dedatos y valores originales solo que
con nombres alternativos, esto sirve para darle ms semntica al lenguaje.
Type alias utiliza la palabra reservada type para funcionar:
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === "string") {
return n;
}
else {
return n();
}
}
los Type alias no solo pueden ser tipos de datos genercos, tambin se pueden utilizar
parametros como por ejemplo:
type Container<T> = { value: T };
El operador & se utiliza para crear un tipo de dato base como por ejemplo:
// FOO
enum FooIdBrand {}
type FooId = FooIdBrand & string;
// BAR
enum BarIdBrand {}
type BarId = BarIdBrand & string;
32
Type Alias
33
Type Union
Type Union
Implica que solo los mtodos que sean iguales de ambas interfaces o clases (solamente el
nombre del mtodo sean iguales, el contenido puede ser distinto) podrn ser utilizados all
donde se utilicen mtodos de unin como el siguiente ejemplo:
interface Bird {
fly();
layEggs(); // Los 2 pueden
}
interface Fish {
swim();
layEggs(); // Los 2 pueden
}
function getAnimal() : Fish | Bird {
var a : Fish;
return a;
}
let pet = getAnimal();
pet.layEggs(); // Esto funcionara
pet.swim() // Esto da error
34
Type Guards
Type Guards
Son las maneras de controlar los tipos de datos\/objetos que se estn utilizando, esto rompe
con la programacin orientada a objetos ya que esto representa un problema para el
polimorfismo, por ejemplo: si estuvieramos haciendo una serie de comprobaciones para que
segn el tipo de clase u objeto se realize una accin u otra en el momento en el que
existiera un objeto o clase que no tuvieramos contemplado tendriamos que modificar todo el
cdigo.
interface Bird {
fly();
layEggs();
}
interface Fish {
swim();
layEggs();
}
function getAnimal() : Fish | Bird {
var a : Fish;
return a;
}
function isFish(pet: Fish |Bird): pet is Fish {
return (<Fish>pet).swim != undefined;
}
let pet = getAnimal();
if(isFish(pet)) {
(<Fish>pet).swim();
console.log('glup');
} else {
console.log('believe i can fly');
pet.fly();
}
35
Desestructuracin
Desestructuracin
La desestructuracin nos permite extraer valores almacenados en arrays u objetos.
Desestructuracin de objetos
var obj = {x: 1, y: 2, z: 3};
console.log(obj.x); // 1
var {x, y, z} = obj;
console.log(x); // 1
Desestructuracin de arrays
var array = [1, 2, 3];
console.log(array[0]); // 1
var [x, y, z] = array;
console.log(x); // 1
36
Estructuracin
Estructuracin
La estructuracin de parmetros es una forma rpida de que por ejemplo una funcin
acepte una gran cantidad de parmetros como array.
function rest(first, second, ...allOthers) {
console.log(allOthers);
}
rest('foo', 'bar'); // []
rest('foo', 'bar', 'bas', 'qux'); // ['bas','qux']
Tambin se puede hacer asignaciones con array, como por ejemplo: ```ts var list = [1, 2]; list
= [...list, 3, 4]; console.log(list); // [1,2,3,4]
37
Promesas
Promesas
Las promesas representa un resultado eventual de una operacin asincrnica, la primera
manera de interactuar con un una promesa o promise es a travs del mtodo then el cual
registra el callback que recivir la respuesta o la razn por la cual la promesa no a podido
ser cumplida.
Estados
Las promesas pueden estar en 3 estados pending , fulfilled y rejected
Pending
Cuando una promesa no se haya terminado an pero an no ha sido rechazada. (a la
espera), y la respuesta podr ser fulfilled o rejected .
Fulfilled
Cuando la respuesta ha sido devuelta y procesada correctamente, no podr cambiar de
estado y el valor no debe cambiar (debido a la promesa, por otro procesamiento s).
38
Promesas
Rejected
Cuando ha ocurrido un error en la promesa, el estado de la transicin no debe cambiar y
debe tener una razn por la cual a sucedido el error la cual no debe cambiar. para obtener
los resultados rejected utilizamos la palabra reservada catch
Cuando digo que algo no debe cambiar quiero decir que deber ser comprobado con
=== .
Ejemplos
Ejemplo de llamada a then
const promise = new Promise((resolve, reject) => {
resolve(123);
});
promise.then((res) => {
console.log('I get called:', res === 123); // Devuelve: true
});
promise.catch((err) => {
// Nuca es utilizado
});
Promesas
Promise.resolve(123)
.then((res) => {
console.log(res); // 123
return 456;
})
.then((res) => {
console.log(res); // 456
return Promise.resolve(123);
})
.then((res) => {
console.log(res); // 123 : Notice that this `this` is called with the resolved
value
return Promise.resolve(123);
})
Tambin se puede hacer que un mtodo catch continue con la cadena de promesas, de la
siguiente manera:
40
Promesas
El hecho de que el primer then al dar un error se salte el siguiente then siendo una
llamada asincrnica, nos provee con un nuevo paradicma el cual nos permite capturar mejor
las excepciones asncronas.
Tambin es posible que algunas funciones puedan devolver promesas como por ejemplo:
41
Promesas
function iReturnPromiseAfter1Second():Promise<string> {
return new Promise((resolve)=>{
setTimeout(()=>resolve("Hello world!"), 1000);
});
}
Promise.resolve(123)
.then((res)=>{
// res is inferred to be of type `number`
return iReturnPromiseAfter1Second();
})
.then((res) => {
// res is inferred to be of type `string`
console.log(res); // Hello world!
});
Promesas en paralelo
42
Promesas
Como habris observado previamente, hasta ahora todos los ejemplos que hemos visto
heran peticiones en serie pero que sentido tiene eso si lo que queremos es una carga
asincrnica de la informacin, pues no mucha es por eso que ahora veremos un ejemplo de
como seran las peticiones en paralelo.
TypeScript
//-------- main.ts --------// Una funcin asincrna simulando la peticin desde el servidor
function loadItem(id: number): Promise<{id: number}> {
return new Promise((resolve)=>{
console.log('loading item', id);
setTimeout(() => { // simulate a server delay
resolve({ id: id });
}, 1000);
});
}
// Cadena (serie)
let item1, item2;
loadItem(1)
.then((res) => {
item1 = res;
return loadItem(2);
})
.then((res) => {
item2 = res;
console.log('done');
}); // overall time will be around 2s
// Paralelo
Promise.all([loadItem(1),loadItem(2)])
.then((res) => {
[item1,item2] = res;
console.log('done')
}); // overall time will be around 1s
Javascript
43
Promesas
//-------- main.js --------// Una funcin asincrna simulando la peticin desde el servidor
function loadItem(id) {
return new Promise((resolve) => {
console.log('loading item', id);
setTimeout(() => {
resolve({ id: id });
}, 1000);
});
}
// Cadena (serie)
let item1, item2;
loadItem(1)
.then((res) => {
item1 = res;
return loadItem(2);
})
.then((res) => {
item2 = res;
console.log('done');
}); // overall time will be around 2s
// Paralelo
Promise.all([loadItem(1), loadItem(2)])
.then((res) => {
[item1, item2] = res;
console.log('done');
}); // overall time will be around 1s
Ejemplo en el playground
44
Generators
Generators
Los generators no pueden ser utilizados en es5 deben ser usados en es6 o superior.
Los generadores son funciones de las que se puede salir y volver a entrar. Su contexto
(asociacin de variables) ser conservado entre las reentradas. Las reentradas son
efectuadas gracias a la palabra reservada yield
Los generadores son funciones que debuelven un generator object , hay dos grandes
motivaciones para utilizar este tipo de funciones, una de ellas es que los generators siguen
la interfaz iterator permitiendo as utilizar los siguientes mtodos next , return y
throw . Y la otra razn la veremos un poco ms adelante.
function* infiniteSequence() {
var i = 0;
while(true) {
yield i++;
}
}
var iterator = infiniteSequence();
while (true) {
console.log(iterator.next()); // { value: xxxx, done: false } para siempre
}
Como se puede apreciar este tipo de funciones devuelve junto con el resultado el estado de
la iteracin, si la iteracin termina bien devuelve false sino true . Aunque eso no significa
que la funcin parar cuando se llegue al final de la iteracin de un array u objeto. por
ejemplo:
function* idMaker() {
let index = 0;
while (index < 3)
yield index++;
}
let gen = idMaker();
console.log(gen.next()); // { value: 0, done: false }
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: undefined, done: true }
// Accede a la variable por que se le ha dicho apesar de que el 'yield' no ha sido efe
ctuado.
45
Generators
Es importante ver que TypeScript nos permitira compilar esto y acceder a una variable que
no existe. Ya que el lenguaje hasta el momento de la ejecucin (tiempo de ejecucin) no
nos permite saber el nmero de veces que utilizamos el next() .
//------ main.ts -------function* generator(){
console.log('Execution started');
yield 0;
console.log('Execution resumed');
yield 1;
console.log('Execution resumed');
}
var iterator = generator();
console.log('Starting iteration'); // Esto se ejecutar antes que nada de dentro del m
todo generator()
console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
$ node main.js
Starting iteration
Execution started
{ value: 0, done: false }
Execution resumed
{ value: 1, done: false }
Execution resumed
{ value: undefined, done: true }
anterior.
Este tipo de funciones tambin permite la inyeccin de variables como por ejemplo:
46
Generators
Console log
Un texto inyectado
{ value: 1, done: false }
47
Generators
Output
foo
Output
foo
Test
48
Generators
La otra gran razn por la cual es tan importante la utilizacin de este tipo de mtodos es
porque con este tipo de mtodos podemos mejorar el sistema de promesas y las peticiones
asncronas. como por ejemplo:
function getFirstName() {
setTimeout(function(){
gen.next('alex')
}, 1000);
}
function getSecondName() {
setTimeout(function(){
gen.next('perry')
}, 1000);
}
function *sayHello() {
var a = yield getFirstName();
var b = yield getSecondName();
console.log(a, b); //alex perry
}
var gen = sayHello();
gen.next();
49
50
Obviamente esto no es lo mismo que lo que se explica en la leccin anterior sino una
versin ms compleja.
51
Clases
Clases
Clases e interfaces
En caso de que queramos poder instanciar una clase, necesitaremos un constructor, ya que
ha diferencia de lenguajes como java no tiene un contructor por defecto. es por eso que si
queremos utilizar la palabra reservada new tenemos que crear un constructor con la
palabra reservada constructor .
interface a {
b: number;
}
interface b extends a {
c: string;
}
class test implements b {
b: number;
c: string;
constructor (b: number, c: string) {
this.b = b;
this.c = c;
}
}
52
Clases
class Startup {
private text: String;
constructor (texto: String) {
this.text = texto;
}
public main () : number {
console.log(this.text);
return 0;
}
}
let s = new Startup("Hola mundo");
s.main();
class Startup {
public static main(): number {
console.log('Hola mundo');
return 0;
}
}
Startup.main();
53
Clases
this.setY(y);
}
// Setters
public setX(x: number) : void{
this.x = x;
}
public setY(y: number) : void{
this.y = y;
}
// Getters
public getX(): number {
return this.x;
}
public getY(): number {
return this.y;
}
public sumar() : number {
return (this.getX() + this.getY());
}
public restar() : number{
return ( this.mayor() - this.menor() );
}
public menor() : number {
if(this.getX() >= this.getY()) {
return this.getY();
}
return this.getX();
}
public mayor() : number {
if(this.getX() >= this.getY()) {
return this.getX();
}
return this.getY();
}
}
let calculo = new Calculo(30,10);
console.log(calculo.restar());
Javascript
54
Clases
55
Clases
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
let button = document.createElement('button');
button.textContent = "Say Hello";
button.onclick = function() {
alert(greeter.greet());
}
document.body.appendChild(button);
TypeScript tambin admite que las clases tengan propiedades estticas compartidas por
todas las instancias de la clase, la manera natural de acceder a estos atributos estticos
sera:
class Something {
static instances = 0;
constructor() {
// Acedemos directamente mediante el nombre de la clase
Something.instances++;
}
}
var s1 = new Something();
var s2 = new Something();
console.log(Something.instances); // 2
Modificadores de clases
TypeScript tambin admite modificadores de accesibilidad o visibilidad como los
mencionados abajo
Accesibles en
public
private
protected
Instancias de clases
No
No
clases
Clases hijas
No
56
Clases
Abstract
abstract podra pensarse que tambin es un modificador de acceso, pero no es as, ya
que no modifica la posibilidad de acceso sino que es ms similar a una interfaz la cual tiene
un "contrato" y este tipo de clases tiene una sere de normas ms estrictas:
Una clase abstracta no puede ser directamente instanciada, por el contrario tiene
que ser utilizada mediante la herencia de dicha clase.
La clase abstracta no puede ser accedida directamente por las clases hijas, son estas
las que tienen que aportar la funcionalidad.
Qu es IIFE?
IIFE o Immediately-Invoked Function Expression Son funciones annimas en las cuales
estar contenido nuestro cdigo js, esto es debido a que de esa forma estaramos creando
algo as como un namespace, es decir, el contenido de esa funcin no sera accesible
desde fuera a no ser que se instanciar o se utilizara herencia o interfaces, el cdigo js
sera algo as:
57
Clases
Javascript ya compilado
58
Clases
Se puede apreciar que la IIFE permite que TypeScript capture facilmente la clase Point
en una variable llamada _super y luego utilizarla en el cuerpo de la clase.
super
En las clases hijas hace referencia a la clase padre, tenemos que tener en cuenta que
super solo deber ser utilizado cuando no haya de por medio fat arrows o funciones de
flecha, ya que en ese caso debera utilizarse la palabra reservada this veamos unos
ejemplos:
Super sin fat arrow
59
Clases
class Base {
log() { console.log('hello world'); }
}
class Child extends Base {
log() { super.log() };
}
Si intentamos utilizar super en esta situacin el compilador nos dar un error. que nos dir
que solo mtodos public o protected son accesibles con la palabra reservada super
Fat arrow
Las funciones fat arrow se utilizan en para:
Omitir la palabr function
var inc = (x)=>x+1;
60
Clases
funcionara.
function Person(age) {
this.age = age
// aqu el this es el objeto y no quien hace la llamada
this.growOld = () => {
this.age++;
}
}
var person = new Person(1);
setTimeout(person.growOld,1000);
setTimeout(function() { console.log(person.age); },2000); // devuelve 2
61
Clases
62
Clases
class Bird {
fly(){
console.log("Pajaro");
}
layEggs(){
console.log("Pone huevos");
}
}
class Fish {
constructor(){
// Solo para el ejemplo
}
swim(){
console.log("PEZ")
}
layEggs(){
console.log("Pone huevos");
}
}
function getAnimal() : Fish | Bird {
var a : Fish = new Fish();
return a;
}
let pet = getAnimal();
console.log(getAnimal());
pet.layEggs();
// ASERCIN
if((<Fish>pet).swim){
(<Fish>pet).swim();
} else if((<Bird>pet).fly) {
(<Bird>pet).fly();
}
Herencia
63
Clases
64
Clases
// Para poder Crear un array con este typo de objetos tenemos que utilizar la clase Pa
dre Ej:
let array : Animal[] = [ new Rhino('Rinocerator'), new Snake("Serpentina"), new Elepha
nt("Elefanton") ];
// El acceso a este ejemplo sera muchisimo ms sencillo
let ej2 = {Rhino: new Rhino('Rinocerator'), Snake: new Snake("Serpentina"), Elephant:
new Elephant("Elefanton")};
console.log(array);
Javascript
Sobrecarga de mtodos
La sobrecarga de mtodos de TypeScript es as:
function a(x: number);
function a(x: String);
function a(x: boolean);
function a(x: Array<number>);
function a(x){
// implementacin de la funcin
}
Este tipo de sobrecarga no tiene mucho sentido porque sera ms simple poner un Any
Mixin
Cuando tenemos una serie de clases de TypeScript las cuales no tienen ninguna relacin
de herencia entre ellas pero necesitamos que tengan comportamientos comunes,
crearemos mixin , para los que hayan visto PHP es algo as como los traits, estos mixin
nos permiten utilizar las interfaces como clases para poder intentar tener un sucedaneo de
herencia multiple, la cual nos permitir modificar el comportamiento de las clases para
poder implementar estos "contratos".
Esto es un mixin en TypeScript a continuacin vamos a explicar paso a paso el siguiente
ejemplo:
// Disposable Mixin
class Disposable {
isDisposed: boolean;
dispose() {
65
Clases
this.isDisposed = true;
}
}
// Activatable Mixin
class Activatable {
isActive: boolean;
activate() {
this.isActive = true;
}
deactivate() {
this.isActive = false;
}
}
class SmartObject implements Disposable, Activatable {
// Este constructos lo que har ser que mostrar por pantalla
// los estados isActive y isDisposed cada 500 ms
constructor() {
setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500);
}
interact() {
this.activate();
}
// Disposable
isDisposed: boolean = false;
dispose: () => void;
// Activatable
isActive: boolean = false;
activate: () => void;
deactivate: () => void;
}
applyMixins(SmartObject, [Disposable, Activatable]);
let smartObj = new SmartObject();
// esto generar una interactuacin cada segundo cambiando el estado de
// `false - false` a `true - true` la primera vez,
// luego como la variable ya valdra `true - true`
// simplemente se dedicara a mostrarla cada segundo
setTimeout(() => smartObj.interact(), 1000);
////////////////////////////////////////
// In your runtime library somewhere
////////////////////////////////////////
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
66
Clases
});
}
En este trozo de cdigo podremos apreciar que hay dos clases distintas y que cada una de
ellas se enfoca en una actividad o capacidad distinta. Ms adelante mezclaremos estas
clases juntas en otra clase para poder obtener ambas capacidades.
// Disposable Mixin
class Disposable {
isDisposed: boolean;
dispose() {
this.isDisposed = true;
}
}
// Activatable Mixin
class Activatable {
isActive: boolean;
activate() {
this.isActive = true;
}
deactivate() {
this.isActive = false;
}
}
Lo siguiente que haremos es crear una clase la cual implementar la combinacin entre las
dos clases previamente vistas.
class SmartObject implements Disposable, Activatable {
Lo primero que podreis apreciar es que en vez de utilizar extends estamos utilizando
implements , esto es debido a que en TypeScript no existe la herencia multiple y utilizando
la palabra reservada implements trata a las clases que se est implementando como
interfaces que deben ser cumplidas. Esto implica que la clase que acabamos de crear debe
tener los mismo mtodos que las dos "interfaces"
// Implementamos Disposable
isDisposed: boolean = false;
dispose: () => void; // esto es lo mismo que declarar una funcin vaca
// Implementamos Activatable
isActive: boolean = false;
activate: () => void;
deactivate: () => void;
67
Clases
El siguiente paso es crear una funcin la cual nos permitir realizar el mixin de cada una de
las propiedades de las clases en el objeto que deseemos
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
derivedCtor.prototype[name] = baseCtor.prototype[name];
});
});
}
Decorators
Para poder utilizar los decoradores tenemos que permitirlo en nuestro tsconfig y escribir
lo siguiente
"experimentalDecorators": true
68
Clases
Class Decorator
69
Clases
Property Decorator
function PropertyDecorator(
target: Object, // The prototype of the class
propertyKey: string | symbol // The name of the property
) {
console.log("PropertyDecorator called on: ", target, propertyKey);
}
class PropertyDecoratorExample {
@PropertyDecorator
name: string;
}
Method Decorator
70
Clases
function MethodDecorator(
target: Object, // The prototype of the class
propertyKey: string, // The name of the method
descriptor: TypedPropertyDescriptor<any>
) {
console.log("MethodDecorator called on: ", target, propertyKey, descriptor);
}
class MethodDecoratorExample {
@MethodDecorator
method() {
}
}
Parameter Decorator
71
Clases
function ParameterDecorator(
target: Function, // The prototype of the class
propertyKey: string | symbol, // The name of the method
parameterIndex: number // The index of parameter in the list of the function's par
ameters
) {
console.log("ParameterDecorator called on: ", target, propertyKey, parameterIndex)
;
}
class ParameterDecoratorExample {
method(@ParameterDecorator param1: string, @ParameterDecorator param2: number) {
}
}
72
Mdulos
EcmaScript 6
Es un lenguaje del lado del cliente y del servidor, es Async + Sync. Segn las
especificaciones de ES6 existen 2 tipos de exportacin:
exportacin con nombre (varias por mdulo)
exportacin por defecto (una por mdulo). de mdulos, unos ejemplos sertan:
Exportacin con nombre (varias por mdulo) - Permite la carga de varias clases
separadas por comas, a la hora de especificar en la variable a que clase se hace
referencia no hace flata poner el .js
Ejemplo 1:
export clas MyClass {...}
import {MyClass} from './class'
Ejemplo 2 (Javascript):
73
Mdulos
Este tipo de carga tambin permite que se puedan exportar todos los mdulo entero y
acceder a las exportaciones con nombre usando la siguiente sintaxis:
//------ main.js -----import * as calc from 'calculos';
console.log(calc.sumar(2, 3)); // 7
console.log(calc.restar(4, 3)); // 1
Exportacin por defecto (una por mdulo) - Los mdulos que solo exporten un nico
valor son muy populares en la comunidad de Node.js y en el desarrollo frontend. Un
mdulo de ES6 puede tomar un valor por defecto en la exportacin (ms informacin
de como es generado el default abajo).
Ejemplo 1:
export default class {...}
import MyClass from './class'
Ejemplo 2 (Javascript):
//------ miFunc.js -----export default function () { ... };
En ES6 tambin podemos hacer esto usando export seguido de una definicin estndar de
lo que vamos a exportar.
74
Mdulos
Lo interesante es que el nombre que le des ser el mismo usara para importar esa parte del
mdulo.
En caso de que este objeto fuera importado en otro archivo el resultado sera el siguiente:
//------ importado.js -----const SECRETO = "Me gustan los robots";
var opciones = {
color: 'rojo',
imagen: false,
};
function suma(a, b) {
return a + b;
}
export default {
SECRETO,
opciones,
suma,
};
A primera vista, tener mdulos de forma nativa en ES6 puede parecer una funcionalidad
intil, despus de todo ya existe varios sistemas de mdulos muy buenos. Pero los mdulos
de ES6 tienen caractersticas que no se pueden agregar con una librera, como una sintaxis
75
Mdulos
reducida y una estructura esttica de modulos (lo que ayuda a optimizar entre otras cosas).
Adems se espera que termine con la fragmentacin entre los sistemas CommonsJS y
AMD.
Tener un nico estandar para mdulos nativo significa:
No ms UMD (Definicin Universal de Mdulos): UMD es un patrn que permite que un
mismo archivo sea usado por distintos sistemas (como CommonJS y AMD). Cuando
ES6 este listo para su uso UMD se volver obsoleto.
Las nuevas API de los navegadores se volveran mdulos en lugar de variables
globales o propiedades como navigator.
No ms objetos como namespaces. Objetos como Math y JSON sirven como
namespaces para funciones en ECMAScript 5. En el futuro, esta funcionalidad la darn
los mdulos.
Import ES6 Exports ES6
CommonJS
Es una libreria que esta hecha principalmente para el lado del servidor y el cliente, es Sync.
Un ejemplo del cdigo JS es:
Ejemplo 1 (javascript):
//------ exportacin.js -----module exports = {
MyClass: MyClass
}
Ejemplo 2 (javascript):
76
Mdulos
Ejemplo 3: (javascript)
77
Mdulos
Tambin se podra importar la clase primero y luego la instanciarla con un valor de vida
inicial. Ejemplo:
var myHealthComponent = require('./HealthComponent.js')(10);
Mdulos
Qu son bundlers?
En la actualidad no todos los navegadores soportan estos tipos de carga de mdulos es por
eso que se suele utilizar bundlers para concatenar, unificar y minimizar los .js finales.
Los dos ms utilizados son:
webpack
browserify
webpack
Su utilidad reside en la fragmentacin de cdigo: no todas las partes de una webapp
requieren todo el cdigo JavaScript, por eso se encarga de cargar slo las partes
necesarias en cada peticin. Adems, funciona con un gran nmero de lenguajes de
plantilla y preprocesadores de JavaScript (TypeScript o CoffeeScript, ReactJS) y CSS
(LESS, SASS). Para que importar diferentes componentes sea sencillo e intuitivo,
Webpack implementa el ya estandarizado RequireJS para la inyeccin de dependencias de
nuestra aplicacin. Ejemplo:
Primero empezaremos con la instalacin de webpack:
npm install -g webpack
HTML5
79
Mdulos
<!DOCTYPE html>
<html lang="ES">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Introduccin a Webpack</title>
<link rel="stylesheet" href="">
</head>
<body>
<!-- carga del script -->
<script type="text/javascript" src="script.js" charset="utf-8"></script>
</body>
</html>
Javascript
//------ mensajes.js -----var mensaje = "Hola, qu tal?"
exports.saludo = mensaje
browserify
Browserify es una librera de Node.js, escrita por substack, uno de los mayores
contribuidores al core de Node.js y con mayor nmero de mdulos publicados en NPM.
Nos permite escribir cdigo JavaScript del cliente, como si estuvisemos programando en
Node.js, es decir, como por ahora no tenemos mdulos de forma nativa en JavaScript
(hasta que se implante el estndar ECMAScript6 que si los trae) hay libreras que se
encargan de imitar ese comportamiento (Caso de Require.js hace un tiempo).
80
Mdulos
Con esta librera, podemos instalar mdulos para el cliente, con NPM, al igual que
hacamos con bower, pero ahora, podemos llamarlos desde nuestro cdigo con la palabra
reservada require, al igual que en Node.js
Ejemplo: Vamos a crear app.persona.js como mdulo para ver como se exportara e
importara en nuestra aplicacin con browserify.
// source/scripts/app.persona.js
var Persona = function(nombre, edad) {
this.nombre = nombre;
this.edad = edad;
var self = this;
return {
saludar: function() {
alert("Hola, mi nombre es " + self.nombre);
},
presentar: function() {
alert("Tengo " + self.edad + " aos.");
}
};
}
module.exports = Persona;
81
Mdulos
Tipo de mdulos
Mdulo global
82
Mdulos
Por defecto cuando escribes un archivo TypeScript como por ejemplo un archivo llamado
a.ts :
Si crearamos otro archivo en el mismo proyecto por ejemplo b.ts y quisieramos utilizar
variables del archivo a.ts podramos hacerlo ya que para TypeScript ambos pertenecen al
namespace global.
//------ b.ts -----var b = a; // Permitido
Mdulos de archivo
Tambien conocidos como mdulos externos. Si utilizamos las palabras reservadas import
o export dentro de un fichero TypeScript estas creando un mbito local de este archivo.
Esto lo que hace es preveer el namespace global. Si volvemos al ejemplo anterior:
//------ a.ts -----export var a = 123;
Utilizar import para variables exportadas solo sirve para quitarlo del namespace global.
La manera de generar en TypeScript mdulos externos es utilizando la palabra reservada
module , mediante la cual podremos encapsula una parte de nuestro cdigo dentro de un
mdulo.
83
Mdulos
Puede haber varios mdulos con el mismo nombre en distintos namespace y si quisieramos
incluirlos los dos podriamos renombrarlos.
Es importante observar la palabra reservada declare la cual nos permitira a la hora de
importar este archivo tener todas las variables delcaradas accesibles, de este modo
podramos acceder a la variable hello como si estuviera en el archivo b.ts .
Namespace
Contexto aislado del resto con lo que podemos trabajar, la diferencia entre module y
namespace es que un mdulo estra normalmente dentro de un archivo y un namespaces
puede ser un conjunto de archivos, permitiendonos as englobar una sere de
clases(archivos) bajo un mismo namespace. En la actualidad el namespace es
considerado un mdulo interno.
Exportacin
//------ namespace.ts -----// Mdulos internos TypeScript
namespace MySpace {
export class MyClass {
public static myProperty: number = 1;
}
}
84
Mdulos
Definitions
Son archivos .d.ts, los cuales contendrn las "reglas" que deberemos cumplir para poder
utilizar adecuadamente libreras externas de javascript, como por ejemplo jQuery. Los .d.ts
suelen ser interfaces.
Los archivos d.ts, no se generan de forma automtica, pero existe un repositorio en github
con todos los distintos d.ts el repositorio se llama typings estos funcionan de la siguiente
forma:
85
Mdulos
86
Sistemas de automatizacin
Sistemas de automatizacin
Porque hoy en da el flujo de trabajo de un desarrollador se ha vuelto ms complejo,
usamos muchas herramientas de desarrollo, por lo cual configurar cada tarea y ejecutarla
manualmente y por separado requiere demasiado tiempo, para solucinar este problama
tenemos sistemas de automatizacin de tareas.
Gulp.js
Gulp.js es un build system(sistema de construccin) que permite automatizar tareas
comunes de desarrollo, tales como la minificacin de cdigo JavaScript, recarga del
navegador, compresin de imgenes, validacin de sintaxis de cdigo y un sin fin de tareas
ms.
Y en esta veremos como Gulp.js manipula los archivos al realizar sus tareas:
87
Sistemas de automatizacin
Como podemos ver, aunque los 2 hicieron la misma tarea Gulp.js no escribi archivos
temporales en el disco duro. Gulp.js realiz 4 operaciones y en cambio Grunt.js realiz
8 operaciones.
Gulp.js utiliza el poder del paquete Node.js vinyl-fs para leer y escribir Streams.
Gulp.js tambin utiliza un paquete Node.js para la secuenciacin, ejecucin de tareas y
dependencias en mxima concurrencia, llamado Orchestrator.
Ms adelante veremos con mayor detalle como trabajan los Streams de Node.js.
Si ests usando Linux o Mac, tal vez necesites anteponer la palabra sudo para poder
ejecutar este comando con los permisos de administrador, as:
sudo npm install -g gulp
88
Sistemas de automatizacin
Npm nos pedir los datos de nuestro proyecto, ya que en esta ocasin slo estamos
haciendo un demo. Simplemente presionaremos Enter a todas las preguntas.
Con esto, Npm nos debe haber creado un archivo llamado: package.json, que contendr
algo parecido a lo siguiente:
{
"name": "gulp-primeros-pasos",
"version": "0.0.1",
"description": "Gulp: Primeros pasos",
"main": "gulpfile.js",
"author": "jansanchez",
"license": "MIT"
}
89
Sistemas de automatizacin
90
Sistemas de automatizacin
/*
* Dependencias
*/
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
/*
* Configuracin de la tarea 'demo'
*/
gulp.task('demo', function () {
gulp.src('js/source/*.js')
.pipe(concat('todo.js'))
.pipe(uglify())
.pipe(gulp.dest('js/build/'))
});
Con esto ya tenemos todo configurado, as que para ponerlo a prueba en nuestra terminal
escribimos lo siguiente:
gulp demo
El cual nos indica que la tarea demo se ejecut con xito en 9 milisegundos.
Para comprobar si se ejecutaron las 2 tareas requeridas, nos dirigimos a la carpeta js/build
y abrimos el archivo todo.js y nos debe mostrar el siguiente contenido:
var sumar=function(r,n){return r+n},restar=function(r,n){return r-n};
Como vemos, con unas simples y limpias lineas de cdigo hemos realizado 2 tareas de
desarrollo comunes(concatenar y minificar archivos .js).
Analizando el gulpfile.js
Ahora vamos a analizar el cdigo que escribimos en nuestro gulpfile.js para entender un
poco ms como funciona Gulp.js.
91
Sistemas de automatizacin
Primero para llevar a cabo las tareas que deseamos, requerimos los siguientes paquetes:
gulp, gulp-concat y gulp-uglify, as:
/*
* Dependencias
*/
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
API - Documentacin
Gulp.js tiene una pequea API, esto te permitir aprender Gulp.js rpidamente.
GULP.TASK()
Con el mtodo gulp.task() definimos una tarea, este mtodo toma 3 argumentos: el nombre
de la tarea, la las tareas de las que depende esta tarea y la funcin que ejecutar al
llamar esta tarea.
En nuestro ejemplo slo usamos 2 parmetros: el nombre y la funcin, as:
/*
* Configuracin de la tarea 'demo'
*/
gulp.task('demo', function () {
// Contenido de la tarea 'demo'
});
Con lo cual declaramos demo como nombre de la tarea y dentro escribimos lo que
deseamos que haga nuestra tarea.
As que si queremos llamar esta tarea tan solo escribimos en nuestra terminal:
gulp demo
Lista de tareas
Una tarea tambin puede actuar como una lista de tareas, supongamos que queremos
definir una tarea que corra otras 3 tareas por ejemplo: imgenes, css y js. Entonces
escribiramos lo siguiente:
gulp.task('estaticos', ['imagenes', 'css', 'js']);
92
Sistemas de automatizacin
Lo que quiere decir que al ejecutar la tarea estaticos con el comando gulp estaticos se
ejecutarn estas 3 tareas.
El detalle es que estas tareas correran asncronamente, osea que corrern todas juntas al
mismo tiempo sin ningn orden de ejecucin.
Entonces, cuando corramos la tarea css, Gulp.js ejecutar primero la tarea imagenes,
esperar a que esta tarea termine y luego recin ejecutar la tarea css.
Y claro, tambin puedes hacer que tu tarea por defecto sea una lista de tareas, as:
gulp.task('default', ['css', 'js']);
Esta tarea ejecutar las tarea css y js, tan solo escribiendo en nuestra terminal:
gulp
gulp.src()
93
Sistemas de automatizacin
El mtodo gulp.src() toma como parmetro un valor glob es decir, una cadena que coincida
con uno o ms archivos usando los patrones que usa el intrprete de comandos de
unix(shell) y retorna un stream que puede ser pipeado a un plugin adicional hacia el
mtodo gulp.dest().
Este parmetro puede ser una cadena o una coleccin(Array) de valores glob.
Gulp.js usa el paquete de Node.js node-glob para obtener los archivos especificados en l
los globs ingresados.
Ejemplos de globs
js/source/1.js coincide exactamente con el archivo.
js/source/*.js coincide con los archivos que terminen en .js dentro de la carpeta
js/source.
js/**/*.js coincide con los archivos que terminen en .js dentro de la carpeta js y
Cada vez que Gulp.js encuentre un archivo que coincida con nuestro patrn, lo ir metiendo
dentro de un Stream, que ser como una coleccin de archivos. Claro, respetando las
propiedades de cada archivo(ruta, etc).
Entonces podemos decir que tendremos todos esos archivos con sus respectivas
propiedades dentro de un Stream, Este Stream puede ser manipulado por Gulp.js.
94
Sistemas de automatizacin
La primera vez lo usamos para leer el Stream y se lo pasamos al plugin concat para que
este realize la concatenacin y as transforme los datos del Stream, as:
.pipe(concat('todo.js'))
La segunda vez lo usamos para leer los datos actuales(js concatenado) y se lo pasamos al
plugin uglify, para que realize la minificacin del archivo concatenado. Todo esto sin
escribir en el disco ningn archivo temporal, as:
.pipe(uglify())
La tercera vez se lo pasamos a el mtodo gulp.dest(), as que veamos que hace este
mtodo.
gulp.dest()
Canaliza y escribe archivos desde un Stream, por lo que puede canalizar a varias carpetas.
Crear las carpetas que no existan y retornar el Stream, por si deseamos realizar alguna
accin ms.
En pocas palabras, sirve para escribir los datos actuales de un Stream.
Y en nuestro ejemplo lo usamos as:
.pipe(gulp.dest('js/build/'))
Con lo cual escribimos los datos resultantes del Stream dentro de la carpeta js/build/.
El cdigo final nos qued as:
95
Sistemas de automatizacin
/*
* Dependencias
*/
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
/*
* Configuracin de la tarea 'demo'
*/
gulp.task('demo', function () {
gulp.src('js/source/*.js')
.pipe(concat('todo.js'))
.pipe(uglify())
.pipe(gulp.dest('js/build/'))
});
As como realiz 2 tareas consecutivas, con Gulp.js se pueden realizar muchas ms.
gulp.watch()
Ver archivos y hacer algo cuando se modifique un archivo. Esto siempre devuelve un
EventEmitter que emite los eventos de cambio.
Tiene 2 formas de usar:
gulp.watch(glob, tareas) gulp.watch(glob, callback).
gulp.watch('js/source/*.js', ['js']);
Con lo cual, cada vez que se modifique un archivo .js que se encuentre dentro de la carpeta
js/source/ automticamente se ejecutar la tarea js.
gulp.watch('js/source/*.js', function(){
/*
* Aqu ira el cdigo de la accin que deseas realizar,
* Cuando hayan cambios en dichos archivos.
*
* Tambin podras ejecutar una tarea mediante el mtodo
* gulp.start('js')
*
* Pero este mtodo no es oficial, le pertenece al
* paquete 'Orchestrator' ya que Gulp hereda los
* mtodos de 'Orchestrator'.
*/
});
96
Sistemas de automatizacin
97
Consejos
Consejos
En este apartado escribiremos algunos consejos que podran llegar a ser utilies en un
futuro.
98
Esto al ser una funcin annima, en realidad, no nos devuelve el objeto literal sino que se
muestra as
function () {
bar: 123
};
Mientras que si lo hacemos de la siguiente forma podremos obtener un objeto literal con
una funcin que utilice fat arrow
var foo = ()=>({
bar: 123
});
99
Clases estticas
Clases estticas
Una caracterstica general de otros lenguajes de programacin es la palabra static para
incrementar la duracin de una variable (no en lo referente a el ambito de la variable), Aqu
tenemos un ejemplo de uso del lenguaje de programacin C :
void called() {
static count = 0;
count++;
printf("Called : %d", count);
}
int main () {
called(); // Called : 1
called(); // Called : 2
return 0;
}
Como javascript o TypeScript no tiene funciones o clases estticas existe una manera de
hacerlo la maner sera la siguinte:
const {called} = new class {
count = 0;
called = () => {
this.count++;
console.log(`Called : ${this.count}`);
}
};
called(); // Called : 1
called(); // Called : 2
100
101
Quines somos?
Quines somos?
102
Quines somos?
103