Laboratorio: TypeScript básico en 1 hora

Clases e interfaces

Define la interfaz Product con los siguientes atributos:

  • price: con el precio del producto como número.
  • description: un texto opcional con la descripción del producto.
  • getName: una función que devuelve un texto con el nombre del producto.

Define la clase BookProduct como una implementación de Product, con los atributos:

  • title: con el título del libro
  • length: con el número de páginas
  • getName: devuelve title.
  • isShort: un método que devuelve true si el libro tiene menos de 200 páginas.

Define la clase ShirtProduct como una implementación de Product, con los atributos:

  • size: una cadena de texto con el tamaño de la camiseta que puede tomar los valores "S", "M", "L" y "XL".
  • getName: devuelve Camiseta más el tamaño separado por un espacio.
  • isSize(size): un método que recibe una cadena de texto con un tamaño y devuelve true si es el mismo que el de la camiseta.

Código

interface Product {}

class BookProduct {}

class ShirtProduct {}

const book = new BookProduct("Otaberra", 186, 19.9);

assertEqual(book.getName(), "Otabbera");
assertEqual(book.isShort(), true);
assertEqual(book.price, 19.9);
assertEqual(book.description, undefined);

const shirt = new ShirtProduct(
  "XL",
  9.99,
  "Camiseta en color rojo",
);

assertEqual(shirt.getName(), "Camiseta XL");
assertEqual(shirt.isSize("L"), false);
assertEqual(shirt.price, 9.99);
assertEqual(shirt.description, "Camiseta en color rojo");

Solución

interface Product {
  price: number;
  description?: string;
  getName(): string;
}

class BookProduct implements Product {
  private title: string;
  private length: number;
  description?: string;
  price: number;
  constructor(
    title: string,
    length: number,
    price: number,
    description?: string,
  ) {
    this.title = title;
    this.length = length;
    this.price = price;
    this.description = description;
  }

  getName() {
    return this.title;
  }

  isShort(): boolean {
    return this.length < 200;
  }
}

class ShirtProduct implements Product {
  private size: string;
  description?: string;
  price: number;

  constructor(size: string, price: number, description?: string) {
    this.size = size;
    this.price = price;
    this.description = description;
  }

  getName() {
    return `Camiseta ${this.size}`;
  }

  isSize(size: string) {
    return this.size === size;
  }
}

const book = new BookProduct("Otaberra", 186, 19.9);

assertEqual(book.getName(), "Otaberra");
assertEqual(book.isShort(), true);
assertEqual(book.price, 19.9);
assertEqual(book.description, undefined);

const shirt = new ShirtProduct(
  "XL",
  9.99,
  "Camiseta en color rojo",
);

assertEqual(shirt.getName(), "Camiseta XL");
assertEqual(shirt.isSize("L"), false);
assertEqual(shirt.price, 9.99);
assertEqual(shirt.description, "Camiseta en color rojo");

Bonus: getters

TypeScript te permite definir métodos get de manera más concisa. Por ejemplo:

class Product {
  private basePrice: number;
  private taxes: number;

  constructor(basePrice: number, taxes: number) {
    this.basePrice = basePrice;
    this.taxes = taxes;
  }

  getTotalPrice() {
    return basePrice + taxes;
  }
}

console.log(new Product(10, 2).getTotalPrice());
// 12

puede transformarse en:

class Product {
  private basePrice: number;
  private taxes: number;

  constructor(basePrice: number, taxes: number) {
    this.basePrice = basePrice;
    this.taxes = taxes;
  }

  get totalPrice() {
    return basePrice + taxes;
  }
}

console.log(new Product(10, 2).totalPrice);
// 12

Nota como utilizamos el modificador get para marcar totalPrice como un getter. Esto nos permite acceder a él como si fuera otro atributo de la clase.

Con esto, en el código anterior transforma getName a un getter:

Código

interface Product {
  price: number;
  description?: string;
  getName(): string;
}

class BookProduct implements Product {
  private title: string;
  private length: number;
  description?: string;
  price: number;
  constructor(
    title: string,
    length: number,
    price: number,
    description?: string,
  ) {
    this.title = title;
    this.length = length;
    this.price = price;
    this.description = description;
  }

  getName() {
    return this.title;
  }

  isShort(): boolean {
    return this.length < 200;
  }
}

class ShirtProduct implements Product {
  private size: string;
  description?: string;
  price: number;

  constructor(size: string, price: number, description?: string) {
    this.size = size;
    this.price = price;
    this.description = description;
  }

  getName() {
    return `Camiseta ${this.size}`;
  }

  isSize(size: string) {
    return this.size === size;
  }
}

const book = new BookProduct("Otaberra", 186, 19.9);

assertEqual(book.name, "Otabbera");
assertEqual(book.isShort(), true);
assertEqual(book.price, 19.9);
assertEqual(book.description, undefined);

const shirt = new ShirtProduct(
  "XL",
  9.99,
  "Camiseta en color rojo",
);

assertEqual(shirt.name, "Camiseta XL");
assertEqual(shirt.isSize("L"), false);
assertEqual(shirt.price, 9.99);
assertEqual(shirt.description, "Camiseta en color rojo");

Solución

interface Product {
  price: number;
  description?: string;
  name: string;
}

class BookProduct implements Product {
  private title: string;
  private length: number;
  description?: string;
  price: number;
  constructor(
    title: string,
    length: number,
    price: number,
    description?: string,
  ) {
    this.title = title;
    this.length = length;
    this.price = price;
    this.description = description;
  }

  get name() {
    return this.title;
  }

  isShort(): boolean {
    return this.length < 200;
  }
}

class ShirtProduct implements Product {
  private size: string;
  description?: string;
  price: number;

  constructor(size: string, price: number, description?: string) {
    this.size = size;
    this.price = price;
    this.description = description;
  }

  get name() {
    return `Camiseta ${this.size}`;
  }

  isSize(size: string) {
    return this.size === size;
  }
}

const book = new BookProduct("Otaberra", 186, 19.9);

assertEqual(book.name, "Otaberra");
assertEqual(book.isShort(), true);
assertEqual(book.price, 19.9);
assertEqual(book.description, undefined);

const shirt = new ShirtProduct(
  "XL",
  9.99,
  "Camiseta en color rojo",
);

assertEqual(shirt.name, "Camiseta XL");
assertEqual(shirt.isSize("L"), false);
assertEqual(shirt.price, 9.99);
assertEqual(shirt.description, "Camiseta en color rojo");
Ejercicio _ / _