TypeScript parte 3: Tipos, Clases, interfaces y genéricos.

Esta es la parte 3 de una guía para aprender TypeScript desde cero en poco tiempo, aquí hablaremos un poco de como crear tipos y clases entre otras.

Si no has leído las partes anteriores puedes acceder a ellas aquí: Parte 1 y Parte 2.

Tipos

En TypeScript podemos crear tipos agregando nombres y tipos de propiedades. Type es un tipo complejo compuesto de múltiples propiedades. Usando el signo de interrogación estableces indefinido como posible valor (esto significa valor opcional)

type Person =
{
    id: number,
    name: string,
    lastName: string,
    phone?: string, //with the question mark you set undefined as a possible value  
}

var newPerson : Person = {id : 1, name: "Miguel", lastName: "Mendez"} ;
newPerson.lastName = "Teheran";

console.log(`I am ${newPerson.name} ${newPerson.lastName}`);

Cuando se utiliza un tipo en una función, se puede utilizar la desestructuración (destructuring) para obtener el valor de propiedades específicas:

const printFullName = ({name, lastName}: Person) =>
{
    console.log(`My fullname is ${name} ${lastName}`);
}
printFullName(newPerson);

Clases

Una clase es una plantilla con código que se utiliza para crear instancias con datos específicos. Una clase puede contener funciones, propiedades, un constructor y datos.

class SmarPhone {

    color: string
    brand: SmartPhoneBrand
    price:number    

    constructor() {
        //default values using constructor
        this.color = "white";
        this.brand = SmartPhoneBrand.Other;
        this.price = 0;
    }

   //you can initialize and create the properties directly in the constructor
    //constructor(public color: string, public brand: SmartPhoneBrand, public price: number) {
    //    this.color = "white";
    //    this.brand = SmartPhoneBrand.Other;
    //    this.price = 0;
    //}

    setPrice(smartPhonePrice: number) : void
    {
        this.price = smartPhonePrice;
    }
}

//example of a enumeration used in the class
const enum SmartPhoneBrand {
    Apple,
    Xiaomi,
    Sansumg,
    Motorola,
    Other
}

var mySmartPhone  = new SmarPhone();
mySmartPhone.brand = SmartPhoneBrand.Apple;

console.log(`my cellphone is ${mySmartPhone.brand} ${mySmartPhone.color}
nad the price is ${mySmartPhone.price}`);

Puede extenderse desde una clase o clase abstracta. Una clase abstracta no se puede implementar.

abstract class Card {
    //creating and initializing the properties using the constructor 
    constructor(public cardNumber: number, public owner: string) {}
}
//you need to use super to pass the parameters to the parent class
class CreditCard extends Card { 

    constructor(public balance: number, cardNumber: number,  owner: string) {
        super(cardNumber, owner);
    }
}
var masterCard = new CreditCard(1000, 11225533645, "Jhon Doe");

Genéricos

Usando generics podemos usar la misma función para 2 o más tipos

function WhatIsThisType<T>(value: T): string {
    return typeof(value);
}

//when you call the function you can specify the type that you want to use
console.log(WhatIsThisType<number>(100)); 
console.log(WhatIsThisType<boolean>(true));
console.log(WhatIsThisType<string>("string value"));

Podemos utilizar interfaces junto con generics:

interface collectionList<T> {
    id: number,
    name: string,
    description: string,
    items: T[] | undefined | null
}

Cuando se utiliza la interfaz anterior, se puede especificar el tipo para la propiedad colecciones y elementos

var newCollection : collectionList<number> = {
    id: 1,
    name: "New collection",
    description: "This is a new collection",
    items: [10, 20, 30]
}

También puede ampliar el uso de genéricos para incluir una propiedad específica de forma predeterminada en el tipo

interface HasId
{
    id:number;
}

class Item implements HasId {
    constructor(public id:number) {}
}

class GenericModel<T extends HasId> {
    items: T[] | undefined

    constructor(public name:string) {}

    getItembyId(id:number) {
        return this.items?.find(p=> p.id === id);
    }
}

Cuando queramos establecer sólo algunos valores de la clase genérica, podemos utilizar Partial

const simpleCollection = {
    name: 'This is a partial collection',
    items: ["Item1", "Item2"]
}

const partialCollection: Partial<collectionList<string>> = simpleCollection;

Interfaces

Una interfaz define la “forma” de los datos. Contiene la definición general y la estructura de un tipo complejo. Define los tipos de datos que se deben pasar entre los componentes de la aplicación. La interfaz es un contrato compartido en el código

interface User
{
    id: number,
    name: string,
    lastName: string,
    password: string
    rol: Rol
    email?: string, // optional parameter using question mark

    resetPassWord(password: string): boolean //you can properties but also functions to an interface (without implementation)
}

interface Rol
{
    id: number,
    rolName: string,
    levelPermission: number
}

Podemos utilizar interfaces para crear objetos que sigan el formato, incluidas las funciones y propiedades:

let newRol : Rol = 
{
    id: 1,
    rolName: "Admin",
    levelPermission: 0
}

let newUser : User = 
{
    id: 1,
    name: "Miguel",
    lastName: "Teheran",
    password: "****",
    rol: newRol,
    resetPassWord: function (password: string): boolean {
        this.password = password;
        return true;
    }
}

Interfaz vs Tipo

  • Las interfaces representan la estructura de datos del objeto
  • El Type es un alias para representar tipos primitivos y objetos como la estructura de datos.
  • Ambos están bien, pero las interfaces son más comunes y más estrictas.
  • Type podría valor tipo primitivo (como string, number, etc…) y también una estructura de tipos
type Person = string |
{   
    id: number,
    name: string,
    lastName: string,
    phone?: string, //with the question mark you set undefined as a possible value
}

Hemos aprendido todas las características generales de TypeScript, ahora estamos listos para comenzar un proyecto con TypeScript y aprender sobre temas avanzados.

Referencia: https://dev.to/mteheran/typescript-ultimate-guide-for-beginners-1dlo

Repositorio: https://github.com/Mteheran/TypeScriptGuide