TypeScript para principiantes, Parte 3 Interfaces

Comenzamos esta serie con un tutorial introductorio que le presentó diferentes características de TypeScript. También le enseñó cómo instalar TypeScript y sugirió algunos IDE que puede usar para escribir y compilar su propio código de TypeScript. 

En el segundo tutorial, cubrimos diferentes tipos de datos disponibles en TypeScript y cómo usarlos puede ayudarlo a evitar muchos errores. Asignando un tipo de datos como un cuerda a una variable en particular le dice a TypeScript que solo desea asignarle una cadena. Al basarse en esta información, TypeScript puede indicárselo más adelante cuando intente realizar una operación que no debe realizarse en cadenas.

En este tutorial, aprenderá acerca de las interfaces en TypeScript. Con las interfaces, puede ir un paso más allá y definir la estructura o el tipo de objetos más complejos en su código. Al igual que los tipos de variables simples, estos objetos también deberán seguir un conjunto de reglas creadas por usted. Esto puede ayudarlo a escribir código con más confianza, con menos posibilidades de error.

Creando nuestra primera interfaz

Digamos que tiene un objeto de lago en su código, y lo usa para almacenar información sobre algunos de los lagos más grandes por área alrededor del mundo. Este objeto de lago tendrá propiedades como el nombre del lago, su área, longitud, profundidad y los países en los que existe ese lago..

Los nombres de los lagos se almacenarán como una cadena. La longitud de estos lagos será en kilómetros, y las áreas serán en kilómetros cuadrados, pero ambas propiedades se almacenarán como números. Las profundidades de los lagos estarán en metros, y esto también podría ser un flotador.. 

Dado que todos estos lagos son muy grandes, sus costas generalmente no se limitan a un solo país. Usaremos una serie de cadenas para almacenar los nombres de todos los países en la costa de un lago en particular. Un booleano se puede usar para especificar si el lago es agua salada o agua dulce. El siguiente fragmento de código crea una interfaz para nuestro objeto lake.

interfaz Lakes nombre: cadena, área: número, longitud: número, profundidad: número, isFreshwater: booleano, países: cadena []

los Lagos La interfaz contiene el tipo de cada propiedad que vamos a utilizar al crear nuestros objetos de lago. Si ahora intenta asignar diferentes tipos de valores a cualquiera de estas propiedades, obtendrá un error. Aquí hay un ejemplo que almacena información sobre nuestro primer lago..

Let first the Lake: Lakes = name: 'Mar Caspio', longitud: 1199, profundidad: 1025, área: 371000, isFreshwater: false, países: ['Kazakhstan', 'Russia', 'Turkmenistan', 'Azerbaijan', 'Iran ']

Como puede ver, el orden en el que asigna un valor a estas propiedades no importa. Sin embargo, no puede omitir un valor. Tendrá que asignar un valor a cada propiedad para evitar errores al compilar el código. 

De esta manera, TypeScript se asegura de que no omitió ninguno de los valores necesarios por error. Aquí hay un ejemplo donde nos olvidamos de asignar el valor de profundidad propiedad para un lago.

deje secondLake: Lakes = nombre: 'Superior', longitud: 616, área: 82100, isFreshwater: true, países: ['Canadá', 'Estados Unidos']

La siguiente captura de pantalla muestra el mensaje de error en Visual Studio Code después de que olvidamos especificar el profundidad. Como puede ver, el error indica claramente que nos estamos perdiendo el profundidad propiedad para nuestro objeto lago.

Hacer propiedades de interfaz opcionales

A veces, es posible que necesite una propiedad solo para algunos objetos específicos. Por ejemplo, supongamos que desea agregar una propiedad para especificar los meses en que se congela un lago. Si agrega la propiedad directamente a la interfaz, como hemos hecho hasta ahora, obtendrá un error para otros lagos que no se congelan y, por lo tanto, no tienen congelado propiedad. De manera similar, si agrega esa propiedad a los lagos que están congelados pero no en la declaración de interfaz, seguirá recibiendo un error.

En tales casos, puede agregar un signo de interrogación (?) después del nombre de una propiedad para establecerla como opcional en la declaración de interfaz. De esta manera, no obtendrá un error por propiedades faltantes o propiedades desconocidas. El siguiente ejemplo debería dejarlo claro..

interface Lakes nombre: cadena, área: número, longitud: número, profundidad: número, isFreshwater: booleano, países: cadena [], congelado ?: cadena [] deje secondLake: Lakes = nombre: 'Superior', profundidad: 406.3, longitud: 616, área: 82100, isFreshwater: true, países: ['Canadá', 'Estados Unidos'] deje thirdLake: Lakes = nombre: 'Baikal', profundidad: 1637, longitud: 636, área: 31500 , isFreshwater: true, países: ['Rusia'], congelado: ['enero', 'febrero', 'marzo', 'abril', 'mayo']

Uso de firmas de índice

Las propiedades opcionales son útiles cuando muchos de sus objetos las van a usar. Sin embargo, ¿qué pasaría si cada lago también tuviera su propio conjunto único de propiedades como actividades económicas, la población de diferentes tipos de flora y fauna que florece en ese lago o los asentamientos alrededor del lago? Agregar tantas propiedades diferentes dentro de la declaración de la propia interfaz y hacerlas opcionales no es lo ideal.

Como solución, TypeScript le permite agregar propiedades adicionales a objetos específicos con la ayuda de firmas de índice. Agregar una firma de índice a la declaración de interfaz le permite especificar cualquier número de propiedades para los diferentes objetos que está creando. Necesitas hacer los siguientes cambios en la interfaz.. 

En este ejemplo, he usado una firma de índice para agregar información sobre diferentes asentamientos alrededor de los lagos. Dado que cada lago tendrá sus propios asentamientos, el uso de propiedades opcionales no habría sido una buena idea.

interface Lakes nombre: cadena, área: número, longitud: número, profundidad: número, isFreshwater: boolean, países: cadena [], congelado ?: cadena [], [extraProp: cadena]: cualquiera let fourthLake: Lakes =  nombre: 'Tanganica', profundidad: 1470, longitud: 676, área: 32600, agua dulce: verdadero, países: ['Burundi', 'Tanzania', 'Zambia', 'Congo'], kigoma: 'Tanzania', kalemie: 'Congo', Bujumbura: 'Burundi'

Como otro ejemplo, digamos que estás creando un juego con diferentes tipos de enemigos. Todos estos enemigos tendrán algunas propiedades comunes como su tamaño y su salud. Estas propiedades se pueden incluir directamente en la declaración de la interfaz. Si cada categoría de estos enemigos tiene un conjunto único de armas, esas armas pueden incluirse con la ayuda de una firma de índice.

Propiedades de solo lectura

Cuando trabaje con diferentes objetos, es posible que deba trabajar con propiedades que solo deben modificarse cuando creamos el objeto por primera vez. Puedes marcar estas propiedades como solo lectura En la declaración de interfaz. Esto es similar a usar el const palabra clave, pero const se supone que se utiliza con variables, mientras que solo lectura es para propiedades.

TypeScript también le permite hacer matrices de solo lectura usando ReadonlyArray. La creación de una matriz de solo lectura resultará en la eliminación de todos los métodos de mutación de la misma. Esto se hace para asegurarse de que no puede cambiar el valor de los elementos individuales más adelante. Este es un ejemplo del uso de matrices y propiedades de solo lectura en declaraciones de interfaz.

interfaz Enemigo readonly tamaño: número, salud: número, rango: número, readonly daño: número let tank: Enemy = tamaño: 50, salud: 100, rango: 60, daño: 12 // Esto es Okay tank. salud = 95; // Error porque 'daño' es de solo lectura. tank.damage = 10;

Funciones e interfaces

También puede utilizar interfaces para describir un tipo de función. Esto requiere que le de a la función una firma de llamada con su lista de parámetros y tipo de retorno. También debe proporcionar un nombre y un tipo para cada uno de los parámetros. Aquí hay un ejemplo:

interfaz EnemyHit (nombre: Enemy, damageDone: number): number;  deja que tankHit: EnemyHit = function (tankName: Enemy, damageDone: number) tankName.health - = damageDone; return tankName.health; 

En el código anterior, hemos declarado una interfaz de función y la hemos utilizado para definir una función que resta el daño causado a un tanque de su salud. Como puede ver, no tiene que usar el mismo nombre para los parámetros en la declaración de interfaz y la definición para que el código funcione.

Pensamientos finales

Este tutorial le presentó las interfaces y cómo puede usarlas para asegurarse de que está escribiendo un código más sólido. Ahora debería poder crear sus propias interfaces con propiedades opcionales y de solo lectura.. 

También aprendió cómo usar firmas de índice para agregar una variedad de otras propiedades a un objeto que no están incluidas en la declaración de interfaz. Este tutorial fue pensado para que pueda comenzar con las interfaces en TypeScript, y puede leer más sobre este tema en la documentación oficial..

En el siguiente tutorial, aprenderá acerca de las clases en TypeScript. Si tiene alguna pregunta relacionada con las interfaces, hágamelo saber en los comentarios..