TypeScript Dia 3 - Classes, Interfaces y Extensión de Tipos

Vídeo Guía

Vídeo 2: Typescript Dia 2- Gramática y Sintaxis

Hola a todos, bienvenidos al día número 3, en este curso o en esta serie de TypeScript. Durante el día de hoy vamos a hablar sobre clases, interfaces y extendiendo tipos, espero les agrade esta sesión muchas gracias.
Empecemos hablando sobre clases entonces, así como en cualquier otro lenguaje de programación orientado a objetos, en TypeScript las clases tienen campos, constructores, propiedades y funciones. Al definir una clase utilizamos la palabra class y cerramos con llaves {}, así como en c# y java por ejemplo y luego definimos adentro nuestros campos, constructores, propiedades y funciones.

alt text

Entonces como ya saben las clases actúan como contenedores que encapsulan código para que puedan ser consumidos de una manera más fácil.

Entonces empezamos, lo primero que ven ahí, es un campo de tipo String llamado engine, con el engine: Estamos tipiando ese campo, luego con la palabra cable constructor, creamos un constructor obviamente, pero ese constructor puede tener parámetros de entrada, en este caso estamos asignando un parámetro llamado engine de tipo String y luego le estamos asignando al capo local this.engine lo que viene en ese parámetro.

alt text

También hay una forma más sencilla de hacerlo y es en el constructor al poner public, entonces digamos que estamos declarando el campo implícitamente, entonces estamos ignorando la primera línea en el ejemplo que ven en sus pantallas.
Funciones, las funciones, la única diferencia de JavaScript es que no tiene la palabra FUNCTION, pero igual tiene parámetros de entrada pueden ser tipiados o no tipiados digámoslo así ósea que pueden tener number o String por ejemplo o simplemente están sin definir, así como lo vemos en esta diapositiva con la función Star () y Stop ().

alt text

En Clases también podemos tener propiedades, asi como tenemos un campo de tipo String llamado engine, en la parte superior el cual es privado también podemos tener gets y sets, para acceder a ese variable, pára encapsular digamos que la información. Entonces tenemos el get, que es como si fuera una función por que tiene parentecis(), es una sintaxis un poco diferente a c# o java y retorna this.engine. Y tenemos el set, que recibe un valor de tipo String y luego setea con ese valor la propiedad engine, obviamente en ese set, hacemos una validación de que ese valor no sea indefinido y en caso de que eso suceda, entonces lanzamos un error.

alt text

Usando tipos complejos, las clases de por sí pueden ser parámetros, si entonces en la parte superior vemos que hay una clase de tipo engine, cuyo constructor recibe dos valores horsePower que es un number y engineType que es un String, como pueden ver tiene las palabras public, ósea que implícitamente estamos definiendo propiedades y en la parte inferior estamos creando una clase carro, que tenemos un campo de tipo engine y ese campo se recibe como parámetro en el constructor, entonces es una instancia del objeto engine la que estamos recibiendo como parámetro.

alt text

Como se instancia un tipo, simplemente con la palabra clave new y luego el objeto y los parámetros que reciba, entonces primero declaramos un motor var engine = new Engine, recibimos los tipos (300,”V8”) y en segunda instancia var car = new Car (engine) y recibimos ese primer tipo que habíamos instanciado en el primer paso.

alt text

Casteo de tipos, es importante entonces en este momento en la primera parte tenemos document.createElement(“table”), que retorna un HTMLTableElement, la primera línea fallaría porque no estamos haciendo un casting, para castear un elemento es importante la sintaxis que ven en la parte inferior de la pantalla, que es muy parecida a generics en c# por ejemplo, simplemente le damos var table : el tipo luego igual (=), luego otra vez el tipo pero en la sintaxis tipo generics y luego la función que nos retornaría ese tipo.

alt text

Definiciones de tipos, entonces por defectos siempre en cualquier proyecto va existir (lid.ts file) que son los type definition files del DOM, es decir del Document Object Model, todo lo que tenga que ver con window o con document está definido en este archivo y de esa manera podemos utilizarlo en nuestros archivos de TypeScript. Existe una página que se llama http://definitelyped.org/ que la ven en la parte inferior donde están todos o al menos el 90 % de los types de las librerías más comunes, como Angular, JQuery, entonces si alguna vez ustedes se preguntaban si podían utilizar TypeScript con jQuery, con Angular es totalmente posible, utilizando estos type definition files.

alt text

Ahora vamos a ver algunos ejemplos, entonces tenemos nuestra clase Engine, el cual tiene un constructor, que recibe dos parámetros uno de tipo number y otro de tipo String, el primer parámetro es horsePower y el segundo parámetro es engineType.

alt text

Luego tenemos la clase Car que tiene un campo de tipo Engine, ósea del tipo de arriba, estas clases pueden estar en archivos diferentes no es necesario de que estén en los mismos archivos, la clase Car tiene como constructor, un constructor con un parámetro que recibe una instancia del tipo Engine que es el de la parte superior y luego tenemos una propiedad, porque es propiedad, porque tenemos un set y un get, así como lo habíamos visto en las diapositivas.

alt text

Luego en la parte inferior tenemos simplemente, una función Star, que no devuelve nada y más abajo, ya cuando la aplicación empieza, lo que estamos instanciando una clase, estamos instanciando un objeto de la clase Engine y luego instanciando un objeto dela clase Car pero que recibe como parámetro la instancia del tipo engine, luego simplemente con lo que llamamos dod noteccion car.engine.engineType, podemos obtener el valor de esa propiedad y luego con Car.Star() podemos invocar una función.

alt text

Esto es todo por el vídeo de definiendo clases, en el próximo vídeo corto y en los próximos dos digamos, hablaremos sobre extendiendo tipos y hablaremos sobre interfaces.

Ahora hablemos de extendiendo tipos con TypeScript o en otras palabras Herencia, la palabra clave en TypeScript es extends, no es con dos puntos como en c#, por ejemplo, entonces simplemente con la palabra clave extends se hereda la clase de la parte derecha de extends. Las clases heredadas deben tener su constructor y en el constructor se deben hacer un llamado a la función súper, que es para llamar al constructor de la clase base, esto es de carácter obligatorio

alt text

Un ejemplo, tenemos la clase Auto que tiene su constructor engine, y luego tenemos la clase Truck que extiende o hereda de Auto, es decir Truck por herencia también tendría un engine. Truck tiene un constructor que recibe el parámetro engine, pero también recibe si es 4*4 de tipo boolean y luego con la palabra clave super lo que estamos haciendo es llamar al constructor de la clase base.

alt text

Entonces aquí tenemos, digamos que este mismo ejemplo, tenemos el constructor de engine, luego en la parte inferior tenemos una clase de tipo Accessory.

alt text

Luego tenemos una clase de tipo Auto, con sus propiedades y sus campos privados o públicos.

alt text

Vamos a bajar y luego por ejemplo tenemos la clase Truck, que hereda de Auto, obviamente tenemos bedlength como una propiedad o un campo y fourbyFour, luego tenemos un constructor, que recibe varios parámetros, uno de esos parámetros es Engine; y ese engine lo podemos utilizar en la llamada al super, como ustedes pueden ver, super recibe parámetros (basePrice, engine, make, model).

alt text

Si nos venimos a la clase Auto también recibe cuatro parámetros, que son los mismos que están ahí. Luego podemos crear una instancia de Truck, y como pueden ver el segundo parametro de Truck es un engine y aquí mismo podemos instanciarlo con la palabra new, ósea estamos dentro de la misma instanciación de Truck, estamos instanciando engine y luego obviamente podemos llamar a las funciones que requeremos, entonces de esta manera podemos heredar o hacer clases que hereden de otras. Esto es todo por este video.

Ahora hablemos sobre interfaces, entonces suponiendo que tenemos una fábrica que requiere que todos los motores sean construidos siguiendo una interfaz estándar, entonces podríamos crear muchos motores que tengan esa misma interfaz pero que sean diferentes, entonces obviamente si lo aplicamos contra la vida real, un motor tiene que prenderse y tiene que poder apagarse, si es v8, v12, lo que sea, es muy diferente, las válvulas, el aceite que pueda quemar por ejemplo son cosas de implementación especifica del Engine, pero todas tienen inicio y parada o apagar.

alt text

Como se define una interfaz, entonces, una interfaz se define con la palabra interface, luego el nombre de la interfaz que por estándar ya en lenguajes de programación siempre tienen la letra I, antes de la palabra. En este caso IEngine y luego definimos los métodos o las propiedades que vamos a utilizar, en este caso simplemente estamos diciendo que la interfaz IEngine debe tener dos funciones una que es Star y otra que es Stop.

alt text

Entendamos un poquito más esas firmas de esos métodos, para la función Star acepta un parametro que se llama callback, ese callback es como una función que recibe dos parámetros, StartStatus es boolean y engineType es String y no retorna nada como tal, esto es la firma como tal de esa función que debemos implementar, cualquier clase que implemente la interfaz engine debe escribir o sobre escribir, digámosle así implementar en la función Star.

alt text

Las interfaces no solamente para funciones, también pueden ser para propiedades como en este caso vemos la propiedad tipo engine, que a su vez es de tipo IEngine, tenemos otras con tipos de datos nativos como números y strings, pero como pueden ver hay algunas que tienen el signo de interrogación, que significan que son miembros opcionales es decir no es necesario implementarlos.

alt text

Como se implementa una interfaz, simplemente con la palabra clave implemts ala izquierda del nombre de la interfaz, a la derecha de nombre de la clase, obviamente tenemos un constructor y tenemos las funciones implementadas, es decir el Star y el Stop, con la misma firma, muy importante, deben tener la misma firma que definimos en la interfaz como tal.

alt text

Una interfaz también puede ser definida como un tipo, entonces como ustedes pueden ver en la parte superior, tenemos que engine en vez de ser un String es de tipo IEngine, osea de tipo de la interfaz y en el constructor tenemos un parametro data que es de IAutoOptions, también de una interfaz como tal

alt text

Una interfaz puede extender otra interfaz, entonces en la opción que ustedes ven en pantalla tenemos IAutoOptions, con unas propiedades, pero también tenemos ITruckOptions que extiende de IAutoOptions y lo que hace es extender con propiedades adicionales que un auto como tal no tendría, como lo es el tamaño de la cama y como lo es el 4*4 por ejemplo.

alt text

Como se utiliza una interfaz extendida?, lo mismo simplemente utilizamos el ITruckOptions como parametro de entrada del constructor, y dentro del constructor debemos obviamente llamar el constructor base o la palabra clave super.

alt text

Es importante ya que vemos este resumen, que TypeScript provee encapsulación a través de clases, que las clases pueden heredar de otras clases y las interfaces proveen contratos de códigos para asegurar consistencias a través de objetos y por último que las interfaces puedan extender otras interfaces. Prácticamente el video de hoy es el pilar de la programación orientada a objetos, pero enfocado en TypeScript como tal. Entonces de esta manera podemos tener, digamos que definir clases del mundo real para asimilar. Digamos que los objetos y poder abstraer las soluciones de una manera más sencilla.

alt text

Vamos a ver un ejemplo, por último, entonces tenemos, utilizando interfaces, la interfaz IEngine con la función Star y Stop.

alt text

Tenemos la interfaz IAutoOptions y las propiedades tipo número, otras tipo IEngine, otras del tipo de la interfaz definida en la parte superior, luego tenemos la interfaz ITruckOptions que extiende de IAutoOptions.

alt text

Luego tenemos la clase Engine que la implementa IEngine, es decir, que debemos escribir una implementación para la función Star y para la función stop, luego tenemos otro engine, que implementa lo mismo, pero ya en este caso el Star y el Stop vendrían a ser diferentes porque son dos clases diferentes de motores.

alt text

Luego tenemos la clase Accessory,

alt text

y si vamos a mirar donde se utiliza el Accessory por acá, es utilizado como un parametro de entrada de tipo arreglo en una función que se llama addAccesories dentro de la clase Auto.

alt text

Entonces como pueden ver, podemos recibir dentro de otras funciones parámetros de entrada del tipo de una interfaz como tal y con los get y los sets, podemos setiar o obtener esos valores, aquí tenemos con el getAccessoryList, podemos obtener el this. accessoryList, que es de tipo String también.

alt text

Esto es todo por el video número 3 de TypeScript sobre clases, extendiendo tipos e interfaces, espero les haya gustado.