Skip to content

Typing Pizza App part 11

von Schappler edited this page Nov 27, 2024 · 1 revision

Using Generic types on PizzaApp

Now that we aggregated one more concept of TypeScript (generics), it's time for us to refactor our code a bit more, this time by creating a generic function named addToArray.

This function should receive two arguments: an array in which we wish to add a new item and the second argument will be an object that either matches our Pizza type or the Order type.


Applying the solution

The basic structure for the function is really straight forward.

const addToArray = (arr, item) => {
  arr.push(item);
  return arr;
};

The main problem here consists into setting the generic types, which sould leads us to the snippet below:

const addToArray = <I>(arr: I[], item: I): I[] | undefined => {
  arr.push(item);
  return arr;
};
addToArray(menu, { id: pizzaId++, name: 'Chicken Bacon Ranch', price: 12 });
addToArray(orderQueue, { id: orderId++, pizza: menu[2], status: 'completed' });
addToArray(orderQueue, { id: orderId++, pizza: menu[3], status: 'done' });

Even though this definition still empower our code with type checking, there is a small bug that is inserted there when we make use of generics.

If we look closely in our type declarations, there is union type defined for the Order type - this is right where we define the status of an order. Orders can be either ordered or completed. The bug which is inserted into the code by using generics is that TypeScript infers the TYPE of of a generic, basically replacing a pre-defined type also to a "generic" type.

So what happens when you inspect the generic type I for the case of adding an order, we no longer see the type definition where an order status is a literal value.

So, how to fix this bug? The way in which this bug can be fixed is by making explicit generic type declarations, as displayed below:

addToArray<Pizza>(menu, {
  id: pizzaId++,
  name: 'Chicken Bacon Ranch',
  price: 12,
});
addToArray<Order>(orderQueue, {
  id: orderId++,
  pizza: menu[2],
  status: 'completed',
});
Clone this wiki locally