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