Todo lenguaje de programación orientado a objetos tiene tipos de datos más o menos complejos como por ejemplo números, cadenas de caracteres, etc. En TypeScript tenemos soporte para datos tipado orientados a JavaScript.
En esta tercera parte tocaremos los tipos que TypeScript nos brinda para trabajar y sus declaraciones. Veremos algunos ejemplos interesantes en VS Code.
Este documento está dirigido a personas que conocen muy poco o nada sobre el tema o personas que desarrollan tareas de consultoría de desarrollo o que simplemente están interesados en leer e investigar sobre la tecnología alcanzada por esta publicación.
Desarrollo
Para empezar, veremos la estructura básica de cómo debemos declarar una variable:
(alcance) (Nombre): <Tipo>= (Valor);
Ahora que conocemos la estructura básica de declaración comenzaremos con los disponibles.
Tipos
Boolean
Es el tipo más común que podemos encontrar en cualquier lenguaje de tipos. Solamente puede tener 2 valores:posibles true o false.
let isCorrect: boolean = true;
Numeric
Este puede contener cualquier número inclusive con decimal. Como en JavaScript, TypeScript puede guardar números decimales, flotantes.
let money: numeric = 3.34;
let age: numeric = 12;
String
En este tipo de datos guardaremos caracteres, cadenas de caracteres o texto. Podemos utilizar comillas dobles o comillas simples para encerrar el valor. También plantillas de cadenas agregando la notación $(nombre de variable) dentro de nuestros string.
let titlePage: string = "Hola Mundo";
let textInside: string = "This is ${ titlePage }";
Array
Para usar array tenemos 2 formas de hacerlo, una es muy similar a JavaScript la otra es muy similar a lo que se denomina Tipos Genéricos.
let colors: string[] = ["Rojo", "Azul", "Verde"];
let colors: Array&lt;string&gt; = ["Rojo", "Azul", "Verde"];
Tuple
Este tipo es que se denomina comúnmente llave valor. similar a un array, nos permitirá acceder al valor por medio de su llave.
let x: [string, number] = ["Pepe", 2];
console.log(x["Pepe"]);
Enum
Son un conjunto de valores que por default será asignado dependiendo el orden en que se encuentren. También podemos darle valores asignarles nosotros los valores o decirle que empiece la secuencia desde un valor predeterminado declarándose al primero de la lista.
enum Animales{ Perro, Gato, Jirafa, Leon };
enum Animales{ Perro = 1, Gato, Jirafa, Leon };
enum Animales{ Perro = 2, Gato = 5 , Jirafa = 7, Leon = 8 };
let animalTipo = Animales.Jirafa;
Any
La usaremos cuando no sabemos realmente qué valor va a tomar en nuestra aplicación. También podemos usarlo en un array que puede tener valores de los tipos distintos. Es como tener un variable de tipo dinámica.
let valorDesconocido: any = 20;
let valoresDesconocidos: any[] =&nbsp; ["Rojo", 2, true];
Void
Básicamente es lo contrario de lo anterior. Sería no tener ningún tipo. Casi siempre lo usaremos en funciones o métodos que no devuelven un valor.
let sinTipo: void = undefined;
fuction NoDevuelveValor(): void{
console.log("Hola");
}
Null y Undefined
No solo son valores también pueden declararse como tipos. Por defecto son subtipos de los anteriores esto quiere decir que podemos asignar este valor a un tipo como numérico o string.
let sinTipo: number = null;
Never
Representar valores que nunca ocurrirán. Podría usarse por ejemplo en una función que siempre va devolver un error ya que en realidad no devuelve nada. No podemos asignarle never a ningún tipo solamente puede asignarse a sí mismo.
function lanzarError(mensaje: string): never{
throw new Error(mensaje)
}
Aserciones de tipo
De esta forma podemos decirle al compilador que confíe en nosotros para asignarle un tipo. Es similar a Cast de otros lenguajes. Podemos usarlo de 2 formas:
let algunValor: any = 123;
let stringLengh: number (&lt;string&gt; algunValor).length;
let stringLengh: number (algunValor as string).length;
Declaraciones de variables
Tenemos 2 let y const. Let es muy similar a usar var y const es como cualquier constante en los lenguajes de programación evitando que se cambie su valor una vez asignado.
Var
La declaramos igual JavaScript:
var nombre = "Jorge";
Las variables de tipo var pueden estar declaradas en cualquier bloque. Hay que tener en cuenta que al declararla como var puede ser accedida desde bloques superiores. No es conveniente usar var debido a que puede causarnos muchos problemas.
Let
Este viene a solucionar el problema que tenemos con var y su diferencia no está en la sintaxis sino en la semántica:
let nombre = "Jorge";
Al utilizar let estamos diciendo que la variable tiene el alcance del bloque en el cual fue declarado. Esto quiere decir que no pueden ser alcanzadas desde fuera del bloque donde se encuentra.
Const
Este tipo de declaración tienen las mismas características de let pero al asignarle un valor no podrá ser cambiada en ningún momento posterior.
const nombre = "Jorge";
Al utilizar let estamos diciendo que la variable tiene el alcance del bloque en el cual fue declarado. Esto quiere decir que no pueden ser alcanzadas desde fuera del bloque donde se encuentra.
Clases
En JavaScript siempre utilizamos funciones y el patrón prototipo para hacer uso de clases y herencia. Si están familiarizados con C# o Java tal vez nos resulte bastante incómodo en Javascript. Por esto, TypeScript, nos da la posibilidad de usarlas del modo como cualquier lenguaje orientado a objetos. También nos brindara compatibilidad futuras implementaciones de las especificaciones ECMAScript. Veamos:
class Persona {
nombre: string;
constructor(_nombre: string) {
this.nombre = _nombre;
}
greet() {
return "Hello, " + this.nombre;
}
}
let fernando = new Persona("Fernando");
Como comenté antes, es bastante más familiar que como lo usamos en JavaScript. Algunos puntos para tener en cuenta:
- this hace referencia a la misma clase.
- El constructor, a diferencia de los lenguajes que ya conocemos siempre debe llamarse constructor.
- En las funciones no es necesario agregar la palabra function.
Como cualquier lenguaje de programación orientado a objetos tenemos herencia. Esto lo haremos por medio de la palabra reservada extends como vemos en el ejemplo:
class Estudiante extends Persona{
constructor(nombre: string) {
super(name);
}
greet() {
return super.greet();
}
}
En el ejemplo podemos ver la palabra super que hace referencia a la clase de la cual heredamos.
Modificadores
TypeScript nos da 3 tipos de modificadores de acceso, públicos, privados y protegidos.
Público
Por defecto serán declarados como públicos, esto hará que podamos acceder desde cualquier lugar del programa. Podemos marcarlo implícitamente si lo queremos, pero no es necesario.
class Persona {
public name: string;
public constructor(theName: string) {
this.name = theName;
}
}
Private
Cuanto lo declaramos como private el método no podrá ser accesible desde fuera de la clase.
class Persona {
private name: string;
public constructor(theName: string) {
this.name = theName;
}
}
Protected
Funciona como private, pero a diferencia de este pueden ser accedidas solamente por las clases derivadas.
class Persona {
protected name: string;
public constructor(theName: string) {
this.name = theName;
}
}
ReadOnly
Podemos declarar solo lectura, esto hará que no pueda asignarle ningún valor desde fuera de la clase y la asignación debe hacerse en el constructor.
class Persona {
readonly name: string;
public constructor(name: string) {
this.name = name;
}
}
let persona = new Persona("Fernando");
persona.name;
Accessors
En TypeScript tenemos la posibilidad de usar getters y setters.
class Persona {
private name: string;
get Name():string{
return this.name;
}
set Name(_name: string){
this.name = name;
}
}
Tener setters nos da la posibilidad de poder evaluar la asignación de un valor por medio de una comparación.
Propiedades Estáticas
Podremos crear un miembro estático que serán visibles sin la necesidad de instanciar la clase.
class Calculadora {
static result: number = 0;
}
Calculadora.result;
Clases abstractas
Estas clases no pueden instanciarse directamente. Deben ser heredadas obligatoriamente. A diferencia de una interface puede implementar funcionalidades en sus miembros.
abstract class Persona {
abstract getName(): void;
}
class Estudiante extends Persona {
getName(): void {}
}
Interfaces
Son una forma de declarar contratos dentro del código para las clases que tienen características comunes. Veamos la siguiente clase:
class Persona {
public name: string;
public constructor(theName: string) { this.name = theName;}
}
Supongamos que vamos a tener dos clases: estudiantes y profesores. Todos deben cumplir la regla de tener una propiedad name. Para esto usaremos una interface que obligará a que sea implementada:
interface Persona {
name: string;
}
class Estudiante implements Persona{
public name: string;
}
class Profesor implements Persona{
public name: string;
}
Propiedades opcionales
Una buena característica es que podemos declarar variables opciones las cuales no obligan a las clases que implementar a declarar esos miembros. Se hace por medio del carácter?
interface Persona {
name?: string;
}
Propiedades solo lectura
podemos especificar que los miembros deben ser declarados como readonly.
interface Persona {
readonly name: string;
}
Conclusión
Hemos las clases, interfaces y funciones. Si bien el tema puede ser mucho más extenso, con este pantallazo general nos dan la base para poder seguir expandiendo nuestros conocimientos. El segundo acercamiento a los tipos de TypeScript y cómo debemos declararlos. Si conocen C# o Java notaran que las referencias son muy similares, pero respetando las características de JavaScript. El próximo post veremos el tema de interfaces y clases.