Lezioni del modulo (2/2)
Tipi di Utility
TypeScript fornisce diversi tipi di utilità globali (Utility Types) per facilitare le trasformazioni di tipo comuni. Questi tipi sono generici e permettono di creare nuovi tipi a partire da quelli esistenti in modo dichiarativo.
I quattro tipi di utilità più utilizzati sono:
1. Partial<T>
Rende tutte le proprietà di un tipo T opzionali. È estremamente utile per le funzioni di aggiornamento (update/patch) in cui l'utente potrebbe fornire solo un sottoinsieme di campi:
interface User {
id: number;
name: string;
email: string;
}
// Tutte le proprietà di User diventano opzionali: { id?: number; name?: string; email?: string; }
type UserUpdate = Partial<User>;2. Readonly<T>
Rende tutte le proprietà di un tipo T in sola lettura (readonly). Qualsiasi tentativo di riassegnare una proprietà causerà un errore del compilatore a tempo di compilazione:
interface Point {
x: number;
y: number;
}
const p: Readonly<Point> = { x: 10, y: 20 };
// p.x = 5; // Errore: non puoi assegnare a 'x' perché è una proprietà in sola lettura3. Pick<T, Keys>
Crea un tipo selezionando solo un insieme specifico di chiavi (rappresentate da un'unione di stringhe) dal tipo T:
interface Article {
id: number;
title: string;
content: string;
views: number;
}
// Seleziona solo 'title' e 'views': { title: string; views: number; }
type ArticlePreview = Pick<Article, 'title' | 'views'>;4. Omit<T, Keys>
Crea un tipo rimuovendo un insieme specifico di chiavi dal tipo T. È il duale di Pick:
interface Product {
id: number;
name: string;
price: number;
secretVendorCode: string;
}
// Rimuove 'secretVendorCode': { id: number; name: string; price: number; }
type PublicProduct = Omit<Product, 'secretVendorCode'>;5. Record<Keys, Type>
Crea un tipo di oggetto le cui chiavi sono Keys e i cui valori sono di tipo Type. È utilissimo per mappare chiavi a valori, rappresentare dizionari o tabelle hash (key-value maps):
type Page = 'home' | 'about' | 'contact';
interface PageInfo {
title: string;
}
// Crea un dizionario con chiavi 'home' | 'about' | 'contact' e valori PageInfo
const nav: Record<Page, PageInfo> = {
home: { title: 'Home Page' },
about: { title: 'About Us' },
contact: { title: 'Contact Us' },
};Prova tu
Esercizio 1: Aggiornamento Profilo con Partial
Completa la funzione updateProfile che accetta un profilo originale (Profile) e un oggetto di aggiornamenti (updates) in cui tutti i campi di Profile sono opzionali. Deve restituire un nuovo oggetto Profile che combina le proprietà originali con gli aggiornamenti.
Mostra suggerimento
Usa il tipo di utilità Partial<Profile> per il parametro updates, e l'operatore spread per unire gli oggetti: { ...original, ...updates }.
Soluzione disponibile dopo 3 tentativi
Esercizio 2: Rimozione Campi Sensibili con Omit
Dato il tipo UserAccount, definisci un type alias chiamato SafeUser che omette la proprietà sensibile passwordHash.
Mostra suggerimento
Usa type SafeUser = Omit<UserAccount, 'passwordHash'>; per omettere il campo specificato.
Soluzione disponibile dopo 3 tentativi
Esercizio 3: Configurazione Pubblica con Pick e Readonly
Dato il tipo AppConfig, definisci un type alias chiamato PublicConfig che è una versione di sola lettura (Readonly) contenente solo le proprietà apiEndpoint e port selezionate tramite Pick.
Mostra suggerimento
Usa type PublicConfig = Readonly<Pick<AppConfig, 'apiEndpoint' | 'port'>>;
Soluzione disponibile dopo 3 tentativi
Esercizio 4: Dizionario Utenti con Record e Readonly
Data un'interfaccia User con campi id: number e name: string, crea un tipo ReadOnlyUser che rende tutti i campi di User a sola lettura. Successivamente, crea un tipo UserRegistry che rappresenta un dizionario in cui la chiave è una stringa (es. l'id testuale) e il valore è un ReadOnlyUser.
Mostra suggerimento
Usa Readonly<User> per definire ReadOnlyUser, e Record<string, ReadOnlyUser> per il dizionario.
Soluzione disponibile dopo 3 tentativi