Slides de la charla en el MadridJUG sobre TypeScript y su parecido con Java. Se presentan los parecidos entre estos dos lenguajes y sus diferencias más notables.
26. 26
Tipado dinámico
El compilador no te ayuda
Hay que ejecutar los tests (si tienes)
El IDE tampoco te ayuda
No se puede refactorizar de forma automática
El autocompletar es muy limitado
La documentación integrada sólo aparece en
casos muy evidentes
No se puede navegar a la implementación
ES5
27. 27
Orientado a objetos
con prototipos
Existen 3 formas diferentes de implementar
“clases”
Prototipos “a mano”
Simulación de clases con librerías
Patrón módulo usando clousures
ES5
28. 28
Orientado a objetos
con prototipos
ES5
function Empleado(nombre, salario){
this.nombre = nombre;
this.salario = salario;
}
Empleado.prototype.getNombre = function(){
return nombre;
}
Empleado.prototype.toString = function(){
return "Nombre:"+this.nombre+",
Salario:"+this.salario;
}
var empleado = new Empleado("Pepe", 700);
console.log( empleado.toString() );
29. 29
Orientado a objetos
con prototipos
La herencia es “hacky” (aunque ellos dirán
que no se usa mucho...)
Los patrones de diseño OO no se pueden
aplicar directamente (ya que te los has
aprendido...)
ES5
30. 30
Sin modularidad
Para independizar código tienes que usar
patrones basados en funciones
O usar AMD, CommonJS, UMD...
ES5
(function() {
var variableTemporal = "a";
//Otro código…
}());
Immediately-Invoked Function Expression (IIFE)
31. 31
y otras lindezas...
¿this y that?
ES5
function Empleado(nombre, sueldo){
this.nombre = nombre;
this.sueldo = sueldo;
}
Empleado.prototype.alertaAlPulsar(button){
button.onclick = function(){
alert(this.nombre+" "+this.sueldo);
}
}
ERROR: this apunta al objeto en
el que se ha generado el evento
41. 41
Google WebToolkit
En 2006 Google saca una herramienta para
convertir código Java a código JavaScript
JS ultraoptimizado y compatible con los
browsers “incompatibles” del momento
Librería de widgets
42. 42
Google WebToolkit
Pero...
●
Muy acoplado al backend escrito en Java (con su
propio protocolo de comunicación)
●
Desarrollo muy pesado (compilador tardaba,
plugins para ejecutar Java en el navegador…)
●
Complicado usar librerías JavaScript desde código
Java...
44. 44
Nuevo GWT (2.8 beta)
Desarrollado por la comunidad
Mucho más ligero, sin plugins en browsers
Mejor integración Java y JavaScript
No acoplado a backend Java (clientes REST)
Soporta Java 8 (lambda)
45. 45
Nuevo GWT (2.8 beta)
No es una tecnología de front-end genérica
Lo usaría solo para portar código Java
existente a front-end con poco coste
https://news.ycombinator.com/item?id=8554339
47. 47
Deseos de un Javero
desarrollando web frontend
Un lenguaje orientado a objetos con clases y
herencia
Tipado estático
Buenas herramientas con autocompletar,
refactoring, navegación…
49. 49
Deseos de un Javero
desarrollando web frontend
Plugin de eclipse / IntelliJ / Netbeans
Que esté maduro y se use en producción (que
no sea un proyecto en github de cuatro frikis)
Que haya buena documentación en la red,
libros, video cursos...
50. 50
Deseos de un Javero
desarrollando web frontend
Que pueda usar cualquier librería JavaScript
directamente sin complicaciones
Que también lo usen los hipsters frontenders
JavaScripters para que no me miren mal
Que esté apoyado por la comunidad y por las
empresas
55. 55
¿Qué esTypeScript?
Un superconjunto de JavaScript que añade tipos
estáticos
Soporta orientación a objetos con clases y herencia
El compilador de TypeScript genera código JS que
se ejecuta en cualquier browser y en node.js
http://www.typescriptlang.org/
https://www.gitbook.com/book/basarat/typescript/details
57. 57
¿Qué son ES6 y ES7?
ES6 es la última versión de JS (pero ningún
navegador la entiende 100%)
A ES6 ahora le llaman ES2015
ES7 es la versión en desarrollo, aunque algunas
partes son bastante estables
Algunas características de TypeScript se pueden
usar en JavaScript ES6
58. 58
Más características deTS
Funciones lambda (llamadas arrow functions) en
las que this no cambia de significado
Módulos (exportar e importar elementos)
Anotaciones
Programación pseudo-síncrona con async / await
Ámbito de variables de bloque (y error si se declara
dos veces)
For each
...
73. 73
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));
emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){
System.out.println(emp.getNombre());
}
empleados.forEach(emp -> {
System.out.println(emp);
});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));
emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}
empleados.forEach(emp => {
console.log(emp);
});
TypeScript
En Java las clases de la misma carpeta son del mismo paquete.
EnTS cada fichero es un módulo, por eso hay que importar desde otros ficheros
74. 74
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));
emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){
System.out.println(emp.getNombre());
}
empleados.forEach(emp -> {
System.out.println(emp);
});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));
emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}
empleados.forEach(emp => {
console.log(emp);
});
TypeScript
EnTS las variables se declaran con let y tienen ámbito de bloque y no se pueden declarar dos
veces. Se podría usar var (como JS), pero el ámbito sería la función y se podrían redeclarar
75. 75
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));
emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){
System.out.println(emp.getNombre());
}
empleados.forEach(emp -> {
System.out.println(emp);
});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));
emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}
empleados.forEach(emp => {
console.log(emp);
});
TypeScript
EnTS las variables se pueden declarar con tipo (después de :), pero es opcional porque el tipo
se infiere de la inicialización. En Java no lo veremos hasta Java 9 o Java 10
76. 76
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));
emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){
System.out.println(emp.getNombre());
}
empleados.forEach(emp -> {
System.out.println(emp);
});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));
emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}
empleados.forEach(emp => {
console.log(emp);
});
TypeScript
En Java usamos List y ArrayList generificados del API.
EnTS usamos el Array nativo de JS generificado porTS.
77. 77
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));
emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){
System.out.println(emp.getNombre());
}
empleados.forEach(emp -> {
System.out.println(emp);
});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));
emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}
empleados.forEach(emp => {
console.log(emp);
});
TypeScript
En Java List el método es “add”
En el Array de JS el método es “push”
78. 78
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));
emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){
System.out.println(emp.getNombre());
}
empleados.forEach(emp -> {
System.out.println(emp);
});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));
emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}
empleados.forEach(emp => {
console.log(emp);
});
TypeScript
La sintaxis del foreach es muy parecida en Java yTS.
EnTS está basado en iteradores (como en Java)
79. 79
Imports / Listas / foreach / lambdas
List<Empleado> emps = new ArrayList<>();
emps.add(new Empleado('Pepe', 500));
emps.add(new Empleado('Juan', 200));
for(Empleado emp : emps){
System.out.println(emp.getNombre());
}
empleados.forEach(emp -> {
System.out.println(emp);
});
Java
import { Empleado } from "./Empleado";
let emps = new Array<Empleado>();
emps.push(new Empleado('Pepe', 500));
emps.push(new Empleado('Juan', 200));
for(let emp of emps){
console.log(emp.getNombre());
}
empleados.forEach(emp => {
console.log(emp);
});
TypeScript
Las expresiones lambda de Java se llaman arrow function enTS.
Se diferencian en la “flecha” con – o con =
80. 80
Lambdas / Arrow functions
int num = 0;
empleados.forEach(emp -> num++);
System.out.println(num);
Java
let num = 0;
empleados.forEach(emp => num++);
console.log(num);
TypeScript
En Java no se puede acceder a una variable que no sea final (declarada o
efectiva) desde una lambda. EnTS (como en JS) incluso se puede cambiar el
valor de la variable desde la propia arrow function
ERROR
81. 81
Uso de this con la arrow function
function Empleado(nombre, sueldo){
this.nombre = nombre;
this.sueldo = sueldo;
}
Empleado.prototype.alerta(button){
var that = this;
button.onclick = function(e){
alert(that.nombre);
}
}
EnTS una arrow function permite usar this y siempre apunta al objeto
(como Java). En JS si usas funciones this puede cambiar de valor (y es
necesario usar that)
export class Empleado {
private nombre:string,
private sueldo:number){}
alerta(button:HTMLButtonElement){
button.onclick = e => {
alert(this.nombre);
}
}
}
JavaScript TypeScript
82. 82
Anotaciones
import {Component} from 'angular2/core';
@Component({
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent {
}
83. 83
Ventajas deTS respecto a Java
Características que gustarán a los
desarrolladores Java porque simplifica
patrones comunes en Java
85. 85
class Animal {
constructor(private name: string) {
}
}
class Animal {
private name:string;
constructor(name: string) {
this.name = name;
}
}
class Animal {
constructor(private name: string) {
}
}
EnTS se puede declarar un atributo e inicializar su valor desde el constructor declarando
ese atributo como parámetro del constructor y usando el modificar de visibilidad
Definición de atributos
inicializados en constructor
86. 86
class Foo {
get bar() {
return ...;
}
set bar(bar: boolean) {
...
}
}
Getter / Setter con sintaxis de atributo
let foo = new Foo();
if(foo.bar){
foo.bar = false;
}
87. 87
class Foo {
get bar() {
return ...;
}
set bar(bar: boolean) {
...
}
}
Getter / Setter con sintaxis de atributo
let foo = new Foo();
if(foo.bar){
foo.bar = false;
}
88. 88
class Animal { eat() { } }
class Dog extends Animal { woof() { } }
class Cat extends Animal { meow() { } }
let pet: Animal = ...;
if (pet instanceof Dog) {
pet.woof();
} else if (pet instanceof Cat) {
pet.meow();
} else {
pet.eat();
}
Type guards Instanceof / typeof
Disponible también en
Animal
eat()
Animal
eat()
Dog
woof()
Animal
eat()
Cat
meow()
94. 94
Tipos unión
let id: string | number;
id = 3;
...
Id = “3”;
if(typeof id === “string”){
...
}
En JS es habitual que ciertas
variables puedan tener la misma
información aunque se
represente con varios “tipos”.
TS permite definir variables con
varios tipos
95. 95
Compatibilidad de tipos estructural
interface User {
name: string;
}
class Profile {
constructor(public name:string){}
}
let u: User;
u = { name: "Pepe" };
u = new Profile("Pepe");
96. 96
interface User {
name: string;
}
class Profile {
constructor(public name:string){}
}
let u: User;
u = { name: "Pepe" };
u = new Profile("Pepe");
Compatibilidad de tipos estructural
Un objeto Profile puede
asignarse a una variable
de tipo User porque tiene
un atributo name
97. 97
Sobrecarga de métodos “especial”
class TestClass {
someMethod(p1: string): void;
someMethod(p1: number, p2: string): void;
someMethod(p1: string | number, p2?: string): void {
if (typeof p1 === "string"){
console.log("p1");
} else if(p2){
console.log("p2");
}
}
}
Dos métodos con el mismo
nombre deben tener una única
implementación que detecte cual
ha sido llamado.
La implementación tiene que
cubrir todas las cabeceras
98. 98
Limitaciones respecto a Java
El código se ejecuta en una JavaScriptVM, se
aplican todas las limitaciones del mismo
No hay números de 64 bits (ni long ni double)
No hay concurrencia con memoria
compartida
El control del recolector de basura no permite
implementar weak / soft references
99. 99
El lenguaje tiene buena pinta...
¿Pero hay herramientas? Soporte? Librerías
compatibles? Lo usa alguien?
100. 100
Editores / IDEs
Hay plugins para la mayoría de los editores / IDEs
SublimeText Visual Studio
Code
WebStorm
114. 114
Los JavaScripters no se quejan mucho
Los tipos son opcionales
La inferencia de tipos permite no tener que escribir
los tipos constantemente
En realidad es JavaScript con más cosas, así que
todo lo conocido se puede aplicar
Un mismo proyecto puede combinar JS yTS, lo que
facilita migrar un proyecto existente
116. 116
A los que nos gusta nuestro compilador y nuestros
IDEs por fin tenemos un lenguaje de verdad en el
browser
Con este lenguaje desarrollar en Node.js y en el
browser será como estamos acostumbrados
Muchos desarrolladores backend se pasarán a front
con TypeScript
Existen muchas historias de éxito en la red