En aquest tema, explorarem conceptes avançats de manipulació de tipus en TypeScript. Aquests conceptes són essencials per a la creació de biblioteques robustes i per a la gestió de tipus complexos en projectes grans. Aprendrem sobre tipus condicionals, tipus mapats avançats, i altres tècniques que ens permetran escriure codi més flexible i segur.

Continguts

  1. Tipus Condicionals Avançats
  2. Tipus Mapats Avançats
  3. Tipus Recursius
  4. Tipus d'Extracció i Exclusió
  5. Exercicis Pràctics

  1. Tipus Condicionals Avançats

Els tipus condicionals ens permeten definir tipus basats en una condició. Aquests tipus són molt útils per a la creació de tipus dinàmics i flexibles.

Sintaxi Bàsica

T extends U ? X : Y

Exemple Pràctic

type IsString<T> = T extends string ? true : false;

type A = IsString<string>; // true
type B = IsString<number>; // false

Tipus Condicionals Niuats

Podem niuar tipus condicionals per crear lògiques més complexes.

type TypeName<T> = 
    T extends string ? "string" :
    T extends number ? "number" :
    T extends boolean ? "boolean" :
    T extends undefined ? "undefined" :
    T extends Function ? "function" :
    "object";

type T1 = TypeName<string>;  // "string"
type T2 = TypeName<() => void>;  // "function"
type T3 = TypeName<{}>;  // "object"

  1. Tipus Mapats Avançats

Els tipus mapats ens permeten crear nous tipus basats en la transformació d'altres tipus.

Exemple Bàsic

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

interface User {
    id: number;
    name: string;
}

type ReadonlyUser = Readonly<User>;
// ReadonlyUser és { readonly id: number; readonly name: string; }

Tipus Mapats amb Condicions

Podem combinar tipus mapats amb tipus condicionals per crear transformacions més sofisticades.

type Nullable<T> = {
    [P in keyof T]: T[P] | null;
};

type PartialNullable<T> = {
    [P in keyof T]?: T[P] | null;
};

interface User {
    id: number;
    name: string;
}

type NullableUser = Nullable<User>;
// NullableUser és { id: number | null; name: string | null; }

type PartialNullableUser = PartialNullable<User>;
// PartialNullableUser és { id?: number | null; name?: string | null; }

  1. Tipus Recursius

Els tipus recursius ens permeten definir tipus que es refereixen a ells mateixos. Són útils per a la definició de tipus de dades com arbres o llistes enllaçades.

Exemple Pràctic

type JSONValue = 
    | string
    | number
    | boolean
    | null
    | JSONObject
    | JSONArray;

interface JSONObject {
    [key: string]: JSONValue;
}

interface JSONArray extends Array<JSONValue> {}

const example: JSONValue = {
    name: "John",
    age: 30,
    friends: ["Jane", "Doe"],
    address: {
        city: "New York",
        zip: "10001"
    }
};

  1. Tipus d'Extracció i Exclusió

TypeScript proporciona utilitats per extreure o excloure tipus específics d'un conjunt de tipus.

Extract i Exclude

type T1 = Extract<"a" | "b" | "c", "a" | "f">;  // "a"
type T2 = Exclude<"a" | "b" | "c", "a" | "f">;  // "b" | "c"

NonNullable

El tipus NonNullable elimina null i undefined d'un tipus.

type T3 = NonNullable<string | number | undefined>;  // string | number

  1. Exercicis Pràctics

Exercici 1: Tipus Condicionals

Defineix un tipus condicional que verifiqui si un tipus és una funció.

type IsFunction<T> = T extends (...args: any[]) => any ? true : false;

type Test1 = IsFunction<() => void>;  // true
type Test2 = IsFunction<number>;  // false

Exercici 2: Tipus Mapats

Crea un tipus mapat que faci que totes les propietats d'un tipus siguin opcionals i nullables.

type OptionalNullable<T> = {
    [P in keyof T]?: T[P] | null;
};

interface Product {
    id: number;
    name: string;
    price: number;
}

type OptionalNullableProduct = OptionalNullable<Product>;
// OptionalNullableProduct és { id?: number | null; name?: string | null; price?: number | null; }

Exercici 3: Tipus Recursius

Defineix un tipus recursiu per a una estructura d'arbre binari.

interface TreeNode<T> {
    value: T;
    left?: TreeNode<T>;
    right?: TreeNode<T>;
}

const tree: TreeNode<number> = {
    value: 1,
    left: {
        value: 2,
        left: { value: 4 },
        right: { value: 5 }
    },
    right: {
        value: 3,
        left: { value: 6 },
        right: { value: 7 }
    }
};

Conclusió

En aquesta secció, hem explorat tècniques avançades de manipulació de tipus en TypeScript, incloent tipus condicionals, tipus mapats avançats, tipus recursius i utilitats d'extracció i exclusió. Aquests conceptes són fonamentals per a la creació de codi TypeScript robust i flexible. Practica aquests conceptes amb els exercicis proporcionats per consolidar el teu coneixement i prepara't per als temes més avançats que vindran.

© Copyright 2024. Tots els drets reservats