Les guàrdies de tipus (type guards) són una característica poderosa de TypeScript que permeten verificar el tipus d'una variable en temps d'execució. Això és especialment útil quan es treballa amb tipus d'unió, ja que permet assegurar-se que una variable compleix amb un determinat tipus abans de realitzar operacions específiques d'aquest tipus.

Conceptes Clau

  1. Tipus d'Unió: Permeten que una variable pugui tenir més d'un tipus.
  2. Guàrdies de Tipus: Verifiquen el tipus d'una variable en temps d'execució.
  3. Operadors typeof i instanceof: Eines comunes per implementar guàrdies de tipus.

Tipus d'Unió

Abans d'entrar en les guàrdies de tipus, és important entendre els tipus d'unió. Un tipus d'unió permet que una variable pugui tenir més d'un tipus.

let valor: string | number;
valor = "Hola";
valor = 42;

Guàrdies de Tipus amb typeof

L'operador typeof és una manera senzilla de verificar el tipus primitiu d'una variable.

function imprimirValor(valor: string | number) {
    if (typeof valor === "string") {
        console.log(`El valor és una cadena: ${valor}`);
    } else {
        console.log(`El valor és un número: ${valor}`);
    }
}

imprimirValor("Hola");
imprimirValor(42);

Explicació del Codi

  1. Funció imprimirValor: Accepta un paràmetre que pot ser una cadena (string) o un número (number).
  2. Guàrdia de Tipus typeof: Verifica si el tipus de valor és una cadena. Si és així, imprimeix un missatge específic per a cadenes. Si no, assumeix que és un número i imprimeix un missatge per a números.

Guàrdies de Tipus amb instanceof

L'operador instanceof és útil per verificar si un objecte és una instància d'una classe específica.

class Gato {
    maullar() {
        console.log("Miau!");
    }
}

class Gos {
    bordar() {
        console.log("Guau!");
    }
}

function ferSoroll(animal: Gato | Gos) {
    if (animal instanceof Gato) {
        animal.maullar();
    } else {
        animal.bordar();
    }
}

const gat = new Gato();
const gos = new Gos();

ferSoroll(gat);
ferSoroll(gos);

Explicació del Codi

  1. Classes Gato i Gos: Defineixen dos tipus d'animals amb mètodes específics (maullar i bordar).
  2. Funció ferSoroll: Accepta un paràmetre que pot ser un Gato o un Gos.
  3. Guàrdia de Tipus instanceof: Verifica si animal és una instància de Gato. Si és així, crida el mètode maullar. Si no, assumeix que és un Gos i crida el mètode bordar.

Guàrdies de Tipus Personalitzades

També es poden crear funcions de guàrdia de tipus personalitzades per a tipus més complexos.

interface Peix {
    nedar(): void;
}

interface Ocell {
    volar(): void;
}

function ésPeix(animal: Peix | Ocell): animal is Peix {
    return (animal as Peix).nedar !== undefined;
}

function moure(animal: Peix | Ocell) {
    if (ésPeix(animal)) {
        animal.nedar();
    } else {
        animal.volar();
    }
}

const peix: Peix = { nedar: () => console.log("El peix neda") };
const ocell: Ocell = { volar: () => console.log("L'ocell vola") };

moure(peix);
moure(ocell);

Explicació del Codi

  1. Interfícies Peix i Ocell: Defineixen dos tipus d'animals amb mètodes específics (nedar i volar).
  2. Funció ésPeix: És una guàrdia de tipus personalitzada que verifica si un animal és un Peix.
  3. Funció moure: Accepta un paràmetre que pot ser un Peix o un Ocell.
  4. Guàrdia de Tipus Personalitzada: Utilitza la funció ésPeix per verificar si animal és un Peix. Si és així, crida el mètode nedar. Si no, assumeix que és un Ocell i crida el mètode volar.

Exercicis Pràctics

Exercici 1

Escriu una funció que accepti un paràmetre que pot ser un string o un number. Si és un string, retorna la seva longitud. Si és un number, retorna el seu doble.

function processarValor(valor: string | number): number {
    // Implementa la funció aquí
}

Solució

function processarValor(valor: string | number): number {
    if (typeof valor === "string") {
        return valor.length;
    } else {
        return valor * 2;
    }
}

console.log(processarValor("Hola")); // 4
console.log(processarValor(21)); // 42

Exercici 2

Crea una funció que accepti un paràmetre que pot ser un Gato o un Gos (utilitza les classes de l'exemple anterior). La funció ha de retornar un missatge diferent depenent del tipus d'animal.

function descriureAnimal(animal: Gato | Gos): string {
    // Implementa la funció aquí
}

Solució

function descriureAnimal(animal: Gato | Gos): string {
    if (animal instanceof Gato) {
        return "Aquest és un gat.";
    } else {
        return "Aquest és un gos.";
    }
}

console.log(descriureAnimal(new Gato())); // Aquest és un gat.
console.log(descriureAnimal(new Gos())); // Aquest és un gos.

Resum

Les guàrdies de tipus són una eina essencial en TypeScript per treballar amb tipus d'unió i assegurar-se que les operacions es realitzen de manera segura. Utilitzant operadors com typeof i instanceof, així com guàrdies de tipus personalitzades, es pot verificar el tipus d'una variable en temps d'execució i evitar errors comuns. Practicar amb aquests conceptes ajudarà a millorar la seguretat i la robustesa del teu codi TypeScript.

© Copyright 2024. Tots els drets reservats