Cubrimos las principales características del sistema de tipos de TypeScript cuando hablamos de ¿Por qué TypeScript? Los siguientes son algunos puntos clave de esa discusión que no necesitan más explicación:

  • El sistema de tipos en TypeScript está diseñado para ser opcional para que tu JavaScript sea TypeScript.

  • TypeScript no bloquea la emisión de JavaScript en presencia de errores de tipo, permitiéndote actualizar progresivamente tu JS a TS.

Ahora vamos a empezar con la sintaxis del sistema de tipos de TypeScript. Así podrás empezar a usar estas anotaciones en tu código inmediatamente y ver el beneficio. Esto te preparará para una inmersión más profunda más adelante.

Como se mencionó antes los tipos se anotan usando la sintaxis :TypeAnnotation. Cualquier cosa que esté disponible en el espacio de declaración de tipos puede utilizarse como una anotación de tipo.

El siguiente ejemplo demuestra anotaciones de tipo para variables, parámetros de función y valores de retorno de función:

var num: number = 123;
function identity(num: number): number {
return num;
}

Tipos primitivos

Los tipos primitivos de JavaScript están bien representados en el sistema de tipos de TypeScript. Esto significa string, number, boolean como se demuestra a continuación:

var num: number;
var str: string;
var bool: boolean;
num = 123;
num = 123.456;
num = '123'; // Error
str = '123';
str = 123; // Error
bool = true;
bool = false;
bool = 'false'; // Error

Arrays

TypeScript proporciona una sintaxis de tipos dedicada a los arrays para facilitar la anotación y documentación de tu código. La sintaxis consiste básicamente en posponer a cualquier anotación de tipo válida (por ejemplo, :boolean). Le permite realizar de forma segura cualquier manipulación de arrays que haría normalmente y le protege de errores como asignar un miembro del tipo incorrecto. Esto se demuestra a continuación:

var boolArray: boolean;
boolArray = ;
console.log(boolArray); // true
console.log(boolArray.length); // 2
boolArray = true;
boolArray = ;
boolArray = 'false'; // Error!
boolArray = 'false'; // Error!
boolArray = ; // Error!

Interfaces

Las interfaces son la forma principal en TypeScript de componer múltiples anotaciones de tipo en una sola anotación con nombre. Considera el siguiente ejemplo:

interface Name {
first: string;
second: string;
}
var name: Name;
name = {
first: 'John',
second: 'Doe'
};
name = { // Error : `second` is missing
first: 'John'
};
name = { // Error : `second` is the wrong type
first: 'John',
second: 1337
};

Aquí hemos compuesto las anotaciones first: string + second: string en una nueva anotación Name que refuerza las comprobaciones de tipo en miembros individuales. Las interfaces tienen mucho poder en TypeScript y dedicaremos una sección entera a cómo puedes usar eso en tu beneficio.

Anotación de tipo inline

En lugar de crear un nuevo interface puedes anotar cualquier cosa que quieras inline usando :{ /*Structure*/ }. El ejemplo anterior presentado de nuevo con un tipo inline:

var name: {
first: string;
second: string;
};
name = {
first: 'John',
second: 'Doe'
};
name = { // Error : `second` is missing
first: 'John'
};
name = { // Error : `second` is the wrong type
first: 'John',
second: 1337
};

Los tipos inline son geniales para proporcionar rápidamente una anotación de tipo única para algo. Le ahorra la molestia de tener que pensar en un nombre de tipo (potencialmente malo). Sin embargo, si te encuentras poniendo la misma anotación de tipo en línea varias veces es una buena idea considerar la refactorización en una interfaz (o un type alias cubierto más adelante en esta sección).

Tipos especiales

Además de los tipos primitivos que se han cubierto hay unos pocos tipos que tienen un significado especial en TypeScript. Estos son any, null, undefined, void.

cualquier

El tipo any ocupa un lugar especial en el sistema de tipos de TypeScript. Te da una escotilla de escape del sistema de tipos para decirle al compilador que se largue. any es compatible con todos y cada uno de los tipos del sistema de tipos. Esto significa que cualquier cosa puede ser asignada a él y puede ser asignada a cualquier cosa. Esto se demuestra en el siguiente ejemplo:

var power: any;
// Takes any and all types
power = '123';
power = 123;
// Is compatible with all types
var num: number;
power = num;
num = power;

Si estás portando código JavaScript a TypeScript, vas a ser muy amigo de any al principio. Sin embargo, no te tomes esta amistad demasiado en serio, ya que significa que depende de ti asegurar la seguridad de tipos. Básicamente le estás diciendo al compilador que no haga ningún análisis estático significativo.

nulos e indefinidos

Cómo son tratados por el sistema de tipos depende de la bandera del compilador strictNullChecks (cubrimos esta bandera más adelante). Cuando en strictNullCheck:false, el null y undefined literales de JavaScript son efectivamente tratados por el sistema de tipos igual que algo de tipo any. Estos literales pueden ser asignados a cualquier otro tipo. Esto se demuestra en el siguiente ejemplo:

var num: number;
var str: string;
// These literals can be assigned to anything
num = null;
str = undefined;

:void

Use :void para significar que una función no tiene un tipo de retorno:

function log(message): void {
console.log(message);
}

Genéricos

Muchos algoritmos y estructuras de datos en informática no dependen del tipo real del objeto. Sin embargo, usted todavía quiere hacer cumplir una restricción entre varias variables. Un simple ejemplo de juguete es una función que toma una lista de elementos y devuelve una lista invertida de elementos. La restricción aquí es entre lo que se pasa a la función y lo que es devuelto por la función:

function reverse<T>(items: T): T {
var toreturn = ;
for (let i = items.length - 1; i >= 0; i--) {
toreturn.push(items);
}
return toreturn;
}
var sample = ;
var reversed = reverse(sample);
console.log(reversed); // 3,2,1
// Safety!
reversed = '1'; // Error!
reversed = ; // Error!
reversed = 1; // Okay
reversed = ; // Okay

Aquí estás diciendo básicamente que la función reverse toma un array (items: T) de algún tipo T (fíjate en el parámetro de tipo en reverse<T>) y devuelve un array de tipo T (fíjate en : T). Como la función reverse devuelve elementos del mismo tipo que toma, TypeScript sabe que la variable reversed es también de tipo number y le dará seguridad de tipo. De forma similar, si pasas un array de string a la función inversa, el resultado devuelto es también un array de string y obtienes una seguridad de tipo similar, como se muestra a continuación:

var strArr = ;
var reversedStrs = reverse(strArr);
reversedStrs = ; // Error!

De hecho, los arrays de JavaScript ya tienen una función .reverse y TypeScript utiliza efectivamente genéricos para definir su estructura:

interface Array<T> {
reverse(): T;
// ...
}

Esto significa que se obtiene seguridad de tipo al llamar a .reverse sobre cualquier array como se muestra a continuación:

var numArr = ;
var reversedNums = numArr.reverse();
reversedNums = ; // Error!

Discutiremos más sobre la interfaz Array<T> más adelante cuando presentemos lib.d.ts en la sección Declaraciones de Ambiente.

Tipo Unión

Muy comúnmente en JavaScript se quiere permitir que una propiedad sea uno de los múltiples tipos, por ejemplo, un string o un number. Aquí es donde el tipo de unión (denotado por | en una anotación de tipo, por ejemplo, string|number) es útil. Un caso de uso común es una función que puede tomar un solo objeto o una matriz del objeto por ejemplo:

function formatCommandline(command: string|string) {
var line = '';
if (typeof command === 'string') {
line = command.trim();
} else {
line = command.join(' ').trim();
}
// Do stuff with line: string
}

Tipo Intersección

extend es un patrón muy común en JavaScript donde se toman dos objetos y se crea uno nuevo que tiene las características de estos dos objetos. Un tipo de intersección le permite utilizar este patrón de una manera segura como se demuestra a continuación:

function extend<T, U>(first: T, second: U): T & U {
return { ...first, ...second };
}
const x = extend({ a: "hello" }, { b: 42 });
// x now has both `a` and `b`
const a = x.a;
const b = x.b;

Tipo de tupla

JavaScript no tiene soporte de tupla de primera clase. La gente generalmente sólo utiliza un array como una tupla. Esto es exactamente lo que soporta el sistema de tipos de TypeScript. Las tuplas pueden ser anotadas usando : etc. Una tupla puede tener cualquier número de miembros. Las tuplas se demuestran en el siguiente ejemplo:

var nameNumber: ;
// Okay
nameNumber = ;
// Error!
nameNumber = ;

Combinando esto con el soporte de desestructuración en TypeScript, las tuplas se sienten bastante de primera clase a pesar de ser arrays por debajo:

var nameNumber: ;
nameNumber = ;
var = nameNumber;

Alias de tipo

TypeScript proporciona una sintaxis conveniente para proporcionar nombres para anotaciones de tipo que te gustaría usar en más de un lugar. Los alias se crean utilizando la sintaxis type SomeName = someValidTypeAnnotation. A continuación se muestra un ejemplo:

type StrOrNum = string|number;
// Usage: just like any other notation
var sample: StrOrNum;
sample = 123;
sample = '123';
// Just checking
sample = true; // Error!

A diferencia de un interface puedes dar un alias de tipo a literalmente cualquier anotación de tipo (útil para cosas como tipos de unión e intersección). Aquí hay algunos ejemplos más para que te familiarices con la sintaxis:

type Text = string | { text: string };
type Coordinates = ;
type Callback = (data: string) => void;

TIP: Si necesitas tener jerarquías de anotaciones de tipo utiliza un interface. Se pueden utilizar con implements y extends

TIP: Utilice un alias de tipo para estructuras de objetos más simples (como Coordinates) sólo para darles un nombre semántico. También cuando quieras dar nombres semánticos a los tipos Unión o Intersección, un alias de tipo es el camino a seguir.

Resumen

Ahora que puedes empezar a anotar la mayor parte de tu código JavaScript podemos entrar en los detalles de toda la potencia disponible en el sistema de tipos de TypeScript.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.