Aprenda los tipos de datos de TypeScript: de cero a héroe

Hoy en día está de moda en el mundo del desarrollo web: TypeScript . Apuesto a que ya has oído hablar de eso, incluso de pasada. Pero, si no lo has hecho o si solo tienes curiosidad, ¡has venido al lugar correcto, amigo!
Actualmente estoy aprendiendo TypeScript junto con Angular (un artículo sobre esto está en proceso, ¡así que estad atentos!) Porque es lo que nuestra aplicación web está integrada en el trabajo. Decidí escribir algo fácil y simple de seguir para que pueda comenzar a usar los tipos de datos TypeScript.
Dividiré este artículo en dos publicaciones por simplicidad: la primera será una breve descripción de qué es TypeScript, los tipos de datos y algunos ejemplos de apoyo. El segundo artículo se centrará en instalar TypeScript y ejecutarlo localmente en su máquina.

¿Qué es?

Antes de comenzar, aquí hay una descripción súper condensada de TypeScript en mis propias palabras. Es un superconjunto de JavaScript, lo que esencialmente significa que es una forma de JavaScript que le brinda ciertos beneficios junto con toda la grandeza incluida en JavaScript 'vainilla'. Es un lenguaje de código abierto escrito y mantenido por Microsoft.
TypeScript se transpira a JavaScript y se ejecutará en cualquier entorno que ejecute JavaScript nativo. Puede usar TypeScript para aplicaciones de front-end y back-end.
Está escrito al igual que JavaScript, con algunas excepciones que veremos pronto. Aquí hay un ejemplo de algunos TypeScript:
código que muestra mecanografiado
TypeScript en toda su gloria
Intenta no concentrarte en todos los dos puntos y las cosas adicionales que ves arriba, profundizaremos en eso a continuación. En cambio, concéntrese en las cosas que se destacan: solo estamos declarando variables con valores, estas son cadenas, matrices y objetos al igual que en JavaScript.
Otra gran cosa que he aprendido sobre TypeScript es que puedes mezclar JavaScript con el código y no tener problemas para hacerlo. Verifique la captura de pantalla a continuación (esto está dentro de una aplicación Angular):
código mecanografiado y javascript
TypeScript y JavaScript se usan juntos en el mismo archivo

Tipos de datos

Comencemos con las cosas divertidas: ¡tipos de datos! (Hay algunos tipos de datos que no cubriremos, nunca, nulos, indefinidos. Esto es simplemente porque no hay mucho para ellos. Quiero que sepa que existen y si desea profundizar más en esos tipos, aquí hay un enlace a la documentación oficial de TypeScript para su referencia).
TypeScript inferirá el tipo de datos asignado a una variable sin que usted establezca explícitamente el tipo, pero por simplicidad y buena medida, me gusta declarar el tipo de datos al declarar mis variables.
Asignamos tipos de datos simplemente colocando dos puntos después del nombre de la variable pero antes del signo igual:
const {nombre de variable}: {tipo de variable} = {valor de variable }
Esta es la convención de que la mayoría de los tipos de datos TypeScript se declaran con la excepción de funciones y objetos.
Algunos tipos de datos tienen un poco más de complejidad que eso, pero se entiende la idea general. A continuación hay algunas explicaciones breves de los tipos de datos y ejemplos de cómo declararlos.

Booleano

Los booleanos en TypeScript funcionan de la misma manera que en JavaScript. Las variables de tipo de datos booleanos se declaran así:
const myBool: boolean = false;

Cuerda

Las cadenas en TypeScript funcionan de la misma manera que en JavaScript. Las variables de tipo cadena de datos se declaran así:
let myString: string = 'bacon'

Número

Los números en TypeScript funcionan de la misma manera que en JavaScript. Las variables del número de tipo de datos se declaran así:
const myNum: number = 1207;

Formación

Las matrices en TypeScript son, como otros tipos de datos, como matrices en JavaScript. Las variables de la matriz de tipo de datos se declaran de dos maneras separadas:
const myArr: number[] = [12, 90, 71];
La forma anterior es cómo declararía una matriz si todos los elementos dentro de esa matriz son números.
const myArr: Array<number> = [12, 90, 71];
Esta forma de declarar una matriz utiliza el tipo de matriz genérico establecido en número. Funcionalmente, no hay diferencia en cómo estas formas producen el resultado final de declarar una variable con tipo de matriz.
Si los tipos de datos dentro de la matriz son desconocidos o una combinación de tipos de datos, la matriz se puede declarar usando el tipo <any> (este es un tipo en sí mismo que se analiza a continuación):
const myArr: Array<any> = [12, 'thirteen', false];
De esta manera le permitirá mezclar tipos de datos en la matriz.

Tuplas

Las tuplas son un tipo de datos exclusivo de TypeScript. Piense en ellos como matrices con un número fijo de elementos. Este tipo de datos se usa mejor cuando sabe exactamente cuántas variables debe tener. Es posible reasignar el valor de los índices pero no la cantidad de elementos en la tupla.
Las variables de tipo tupla de datos se declaran como una matriz:
let mine: [number, string];
Si nos gustaría cambiar los valores de los elementos, podemos hacerlo siempre y cuando coincidan con los tipos que proporcionamos al declarar nuestra variable:
mine[0] = 14  ✔️
mine[0] = 'Steve' 
Como lo definimos minecomo una tupla, el orden de los valores también es importante y no se puede cambiar. Además, asignar un índice fuera del número definido original producirá un error:
mine[0] = ['Dave', 71]  ❌
mine = [121, 'Dave', 'Steve']; 
mine = [121, 'bacon'];  ✔️

Función

Las funciones pueden ser tan explícitas como quieras que sean. Lo que quiero decir con eso es que podemos aplicar tipos a los parámetros y valores devueltos. A continuación hay dos ejemplos:
una función que devuelve el número 91
Definimos explícitamente el tipo de valor que esperamos que devuelva esta función
Esta función arrojará un error si se devuelve algún valor que no sea un número. Puede devolver una variable solo si esa variable apunta a un número.
También podemos definir los tipos de parámetros que esperamos
Arriba, estamos verificando los parámetros que se pasan a nuestra función. Esta es una excelente manera de evitar errores porque si el número de parámetros está desactivado o si su tipo de datos no coincide con lo que esperamos, TypeScript nos lo hará saber con un error.
Si quiero una función que no devuelva un valor, puedo establecer el tipo como nulo (un tipo de datos que significa la ausencia de datos. Si bien se puede usar al declarar variables, normalmente no se debe a que entonces tendríamos para establecer la variable en nulo o indefinido , solo he usado cuando las funciones no deben tener ningún valor de retorno) y si la función devuelve algo, TypeScript arrojará un error:
una función mecanografiada con el tipo establecido en nulo
Una función con el tipo establecido en nulo
Al establecer el tipo en vacío , estoy siendo explícito acerca de mis devoluciones y estableciendo que si bien esta función aún puede ejecutarse, no debería devolver un valor. Si devuelve un valor, obtendré un error.

Enum

Las enumeraciones son una adición bienvenida (en mi humilde opinión) a los tipos de datos. Piense en ellos como un enfoque más fácil de usar para dar nombres a valores numéricos. Aquí hay un ejemplo de una enumeración:
enum Foods {'bacon', 'tomato', 'lettuce'};
console.log (Foods [0]) // produce 'bacon' console.log (Foods.bacon) // produce 0 console.log (Foods ['lechuga']) // produce 2
También es posible asignar el formato de índice de numeración con enumeraciones también. Muchos lenguajes, incluido C #, tienen enumeraciones y estoy feliz de verlos venir a JavaScript.
Puedes ser tan creativo como quieras con los nombres. Incluso puede cambiar la representación numérica de los índices. Si desea que su primer índice comience en 18 en lugar de 0, es tan simple como:
enum Foods {'bacon'= 18, 'tomato', 'lettuce'};
console.log(Foods['bacon']); // 18
Digamos que teníamos el valor 18 pero no estábamos seguros de a qué se asignó en nuestra Foodsenumeración, también podemos verificar eso:
console.log(Foods[18]); // 'bacon'
Una información notable es que ahora hemos establecido el primer índice para comenzar en 18, el siguiente índice será 19, y así sucesivamente después de la convención de numeración que establezca.
Objeto
Los objetos en TypeScript se definen de manera similar a como se definen los objetos en JavaScript. Podemos ser tan implícitos o explícitos con nuestra definición como queramos o según lo dicte la situación:
let data: = {name: 'Jonathan', age: 30, hobbies: ['running','swimming','coding']};  ✔️
let data: {name: string, age: number, hobbies: string[]} = {name: 'Jonathan', age: 30, hobbies: ['running','swimming','coding']};  ✔️
Al crear objetos, los nombres de las propiedades son inmutables, pero el orden en que aparecen no importa, incluso si los definimos en un orden específico.
Además, podemos tener objetos simples como los anteriores, o podemos definir objetos complejos que aprovechen múltiples tipos de datos como el siguiente (este objeto es solo para fines de demostración):
un tipo de datos de objeto complejo en TypeScript
Aquí establecemos explícitamente tipos de datos cuando sea posible en este objeto complejo

Tipo Alias ​​/ Interfaz

Con el ejemplo de un objeto complejo anterior, puede que piense que esto es increíble, pero ¿qué sucede la próxima vez que necesite crear un objeto complejo? ¿Tengo que volver a escribir todo esto manualmente?
¡No temas, el alias de tipo y los tipos de interfaz están aquí para ayudarte! Un alias de tipo es un tipo de datos que nos permite guardar otros tipos de datos dentro de él y luego hacer referencia a una variable en lugar de reescribir el código una y otra vez.
Como nota al margen, los alias de tipo y las interfaces funcionan de manera muy similar. Ambos nos permiten andamiar un objeto / plano de cómo deben estructurarse nuestros datos. Sin embargo, hay diferencias sutiles que no cubriremos aquí. En cambio, aquí hay una publicación que explica esas diferencias de una manera extremadamente eficiente si desea profundizar más.
Hay detalles entre los dos que debemos tener en cuenta: cuando usamos el alias de tipo, usamos un signo igual (=) para declarar valores, la interfaz no requiere un signo igual.
el tipo de datos de la interfaz en mecanografiado
El tipo de interfaz funciona de manera muy similar al alias de tipo, pero no requiere un signo igual (=).
un tipo de datos de alias en mecanografiado
Los tipos de datos de alias requieren un signo igual (=).
Ahora que tenemos nuestro alias declarado, es hora de hacer uso de ese alias. Cuando queremos "construir" nuestra nueva variable a partir de este alias, simplemente la configuramos como el tipo de datos:
un objeto mecanografiado
El andamiaje de objetos usando los tipos de datos de interfaz / tipo es extremadamente útil :)
Es importante tener en cuenta que la interfaz es específica de TypeScript. Se usa solo en el momento de la compilación para verificar el tipo y detectar cualquier error que pueda haber pasado por alto.  Los datos de nuestra interfaz terminarán en nuestro código final, pero la interfaz en sí está compilada .
Clases
Las clases son, en parte, el verdadero "pan de cada día" de TypeScript (al menos en mi humilde opinión). Manteniendo esta idea de andamiaje de nuevos objetos, las clases nos permiten construir datos de una manera mucho más fácil que simplemente escribirlos manualmente cada vez que surja la necesidad.
Las clases pueden considerarse como planos de cómo se deben definir nuestros datos y qué acciones, si las hay, deberían ser capaces de realizar a través de métodos.
A continuación se muestra un ejemplo de una clase en TypeScript (que es posible gracias a la introducción de clases en ES6):
código mecanografiado que muestra el uso del tipo de datos de clase
Una clase TypeScript, lista para instanciación :)
Ahora, es posible que se pregunte cuáles son las diferencias entre una clase , un alias de tipo y una interfaz . Gran pregunta! La principal diferencia es que las clases se pueden instanciar (podemos crear nuevas instancias de ellas) pero una interfaz no.
Hay, por supuesto, otras diferencias, pero eso no está contenido en el alcance de este artículo. Si desea profundizar, aquí hay un gran artículo que leí para ayudarme a comprender esas diferencias. Encontrará casos de uso para todos ellos, como yo, cuando use TypeScript.
Unión
Este es, de lejos, mi tipo de datos favorito de TypeScript. El tipo de unión nos permite declarar una variable y luego establecerla en un valor "cualquiera o". Lo que quiero decir con eso es que digamos que esperamos que los datos se pasen a una función, pero no estamos seguros de si es una cadena o un número; este es el propósito perfecto (y previsto) del tipo de unión.
Usamos el carácter de canalización simple (en Windows es Shift + la tecla justo arriba de Enter) cuando definimos el tipo. Así es como se vería al definir una variable con tipo de datos de unión:
const numOfDoors: string | string[ ];
Esto le dice a TypeScript que numOfDoors es una variable que puede contener una cadena o una matriz de cadenas.
Aquí hay un ejemplo de esa función que mencioné anteriormente usando el tipo de unión:
código mecanografiado que muestra el uso del tipo de unión
Alguna
Cualquiera es el tipo que establecemos cuando no estamos seguros de los tipos de datos que obtendremos. Tal vez estamos obteniendo algo de un tercero o algunos datos dinámicos y no estamos 100% seguros de si estamos obteniendo una cadena, un número o tal vez una matriz de información. Este es el caso de uso perfecto para cualquier tipo .
código mecanografiado que muestra el uso de cualquier tipo
El tipo de datos any es una forma de optar por no verificar el tipo
Advertiré contra el uso de type any a menos que sea absolutamente necesario porque cuando lo usamos, optamos por una de las características principales de TypeScript: la verificación de tipos.
Sin embargo, este tipo de datos tiene sus casos de uso al igual que todos los tipos de datos mencionados.