Przejdź do głównej treści
eLearner.app
Moduł 4 · Lekcja 2 z 28/14 w kursie~15 min
Lekcje modułu (2/2)

Typy pomocnicze (Utility)

TypeScript udostępnia kilka globalnych typów pomocniczych (Utility Types), które ułatwiają typowe transformacje typów. Typy te są generyczne i pozwalają na deklaratywne tworzenie nowych typów na podstawie już istniejących.

Pięć najczęściej używanych typów pomocniczych to:

1. Partial<T>

Czyni wszystkie właściwości typu T opcjonalnymi. Jest to niezwykle przydatne w funkcjach aktualizacji (update/patch), w których użytkownik może podać tylko podzbiór pól:

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

// Wszystkie właściwości User stają się opcjonalne: { id?: number; name?: string; email?: string; }
type UserUpdate = Partial<User>;

2. Readonly<T>

Czyni wszystkie właściwości typu T tylko do odczytu (readonly). Każda próba ponownego przypisania właściwości spowoduje błąd kompilatora w czasie kompilacji:

TS
interface Point {
  x: number;
  y: number;
}

const p: Readonly<Point> = { x: 10, y: 20 };
// p.x = 5; // Błąd: nie można przypisać wartości do 'x', ponieważ jest to właściwość tylko do odczytu

3. Pick<T, Keys>

Tworzy typ, wybierając tylko określony zestaw kluczy (reprezentowany przez unię ciągów znaków) z typu T:

TS
interface Article {
  id: number;
  title: string;
  content: string;
  views: number;
}

// Wybiera tylko 'title' i 'views': { title: string; views: number; }
type ArticlePreview = Pick<Article, 'title' | 'views'>;

4. Omit<T, Keys>

Tworzy typ, usuwając określony zestaw kluczy z typu T. Jest to przeciwieństwo Pick:

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

// Usuwa 'secretVendorCode': { id: number; name: string; price: number; }
type PublicProduct = Omit<Product, 'secretVendorCode'>;

5. Record<Keys, Type>

Tworzy typ obiektu, którego klucze to Keys, a wartości są typu Type. Jest bardzo przydatny do mapowania kluczy na wartości, reprezentowania słowników lub tablic mieszających (key-value maps):

TS
type Page = 'home' | 'about' | 'contact';

interface PageInfo {
  title: string;
}

// Tworzy słownik z kluczami 'home' | 'about' | 'contact' i wartościami PageInfo
const nav: Record<Page, PageInfo> = {
  home: { title: 'Home Page' },
  about: { title: 'About Us' },
  contact: { title: 'Contact Us' },
};

Spróbuj sam

Ćwiczenie 1: Aktualizacja profilu za pomocą Partial

Ćwiczenie#ts.m4.l2.e1
Próby: 0Ładowanie...

Uzupełnij funkcję updateProfile, która przyjmuje oryginalny profil (Profile) oraz obiekt aktualizacji (updates), w którym wszystkie pola Profile są opcjonalne. Powinna zwracać nowy obiekt Profile łączący oryginalne właściwości z aktualizacjami.

Ładowanie edytora...
Pokaż wskazówkę

Użyj typu pomocniczego Partial<Profile> dla parametru updates oraz operatora spread do połączenia obiektów: { ...original, ...updates }.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie 2: Usuwanie poufnych pól za pomocą Omit

Ćwiczenie#ts.m4.l2.e2
Próby: 0Ładowanie...

Dla danego typu UserAccount, zdefiniuj alias typu o nazwie SafeUser, który pomija poufną właściwość passwordHash.

Ładowanie edytora...
Pokaż wskazówkę

Użyj type SafeUser = Omit<UserAccount, 'passwordHash'>; aby pominąć określone pole.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie 3: Publiczna konfiguracja za pomocą Pick i Readonly

Ćwiczenie#ts.m4.l2.e3
Próby: 0Ładowanie...

Dla danego typu AppConfig, zdefiniuj alias typu o nazwie PublicConfig, który jest wersją tylko do odczytu (Readonly) zawierającą tylko właściwości apiEndpoint oraz port wybrane za pomocą Pick.

Ładowanie edytora...
Pokaż wskazówkę

Użyj type PublicConfig = Readonly<Pick<AppConfig, 'apiEndpoint' | 'port'>>;

Rozwiązanie dostępne po 3 próbach

Ćwiczenie 4: Rejestr użytkowników za pomocą Record i Readonly

Ćwiczenie#ts.m4.l2.e4
Próby: 0Ładowanie...

Dla danego interfejsu User z polami id: number oraz name: string, utwórz typ ReadOnlyUser, który czyni wszystkie pola User tylko do odczytu. Następnie utwórz typ UserRegistry reprezentujący słownik, w którym kluczem jest ciąg znaków (np. tekstowy id), a wartością jest ReadOnlyUser.

Ładowanie edytora...
Pokaż wskazówkę

Użyj Readonly<User> do zdefiniowania ReadOnlyUser oraz Record<string, ReadOnlyUser> dla słownika.

Rozwiązanie dostępne po 3 próbach