window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster już istnieje') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Leki generyczne w TypeScript - The Codest
The Codest
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Branże
    • Fintech i bankowość
    • E-commerce
    • Adtech
    • Healthtech
    • Produkcja
    • Logistyka
    • Motoryzacja
    • IOT
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
  • O nas
  • Nasze Usługi
    • Software Development
      • Frontend Development
      • Backend Development
    • Zespoły IT
      • Programiści frontendowi
      • Backend Dev
      • Inżynierowie danych
      • Inżynierowie rozwiązań chmurowych
      • Inżynierowie QA
      • Inne
    • Konsultacje IT
      • Audyt i doradztwo
  • Wartość dla
    • CEO
    • CTO
    • Delivery Managera
  • Nasz zespół
  • Case Studies
  • Nasze Know How
    • Blog
    • Meetups
    • Webinary
    • Raporty
Kariera Skontaktuj się z nami
Strzałka w tył WSTECZ
2020-05-26
Software Development

Leki generyczne w TypeScript

Mateusz Staniuk

Generics zapewniają fragmenty kodu wielokrotnego użytku, które działają z wieloma typami zamiast z pojedynczym typem. Generics zapewniają sposób traktowania typu jako zmiennej i określania go podczas użytkowania, podobnie jak parametry funkcji.

Generics mogą być używane w połączeniu z funkcjami (tworząc funkcję generyczną), klasami (tworząc klasę generyczną) i interfejsami (tworząc interfejs generyczny).

Użycie podstawowe

Prawdopodobnie używałeś generycznych w przeszłości, nawet o tym nie wiedząc - najczęstszym zastosowaniem generycznych jest deklarowanie tablicy:

const myArray: string[];

Na pierwszy rzut oka nie jest to nic specjalnego, po prostu deklarujemy myArray jako tablica ciągów znaków, ale jest to to samo, co deklaracja generyczna:

const myArray: Array;

Zachowanie przejrzystości

Zacznijmy od bardzo prostego przykładu - jak moglibyśmy przenieść tę waniliową funkcję JS do TypeScript:

function getPrefiledArray(filler, length) {
    return (new Array(length)).fill(filler);
}

Ta funkcja zwróci tablicę wypełnioną podaną ilością wypełniaczwięc długość będzie liczba a cała funkcja zwróci tablicę wypełniacz - ale czym jest wypełniacz? W tym momencie może to być wszystko, więc jedną z opcji jest użycie dowolny:

function getPrefiledArray(filler: any, length: number): any[] {
    return (new Array(length)).fill(filler);
}

Korzystanie z dowolny jest z pewnością generyczna - możemy przekazać dosłownie wszystko, więc "praca z wieloma typami zamiast pojedynczego typu" z definicji jest w pełni pokryta, ale tracimy połączenie między wypełniacz i typ zwracany. W tym przypadku chcemy zwrócić pewną wspólną rzecz i możemy jawnie zdefiniować tę wspólną rzecz jako parametr typu:

function getPrefiledArray(filler: T, length: number): T[] {
    return (new Array(length)).fill(filler);
}

i używać w ten sposób:

const prefilledArray = getPrefiledArray(0, 10);

Ogólne ograniczenia

Przyjrzyjmy się innym, prawdopodobnie bardziej powszechnym przypadkom. Dlaczego właściwie używamy typów w funkcjach? Dla mnie jest to zapewnienie, że argumenty przekazywane do funkcji będą miały pewne właściwości, z którymi chcę wchodzić w interakcje.

Jeszcze raz spróbujmy przenieść prostą waniliową funkcję JS do TS.

function getLength(thing) {
    return thing.length;
}

Mamy do czynienia z nietrywialną zagadką - jak zapewnić, że dana rzecz posiada długość i pierwszą myślą może być zrobienie czegoś takiego:

function getLength(thing: typeof Array):number {
    return thing.length;
}

i w zależności od kontekstu może to być poprawne, ogólnie rzecz biorąc, jesteśmy nieco ogólnikowi - będzie działać z tablicami wielu typów, ale co, jeśli tak naprawdę nie wiemy, czy rzecz powinna zawsze być tablicą - może rzecz jest boiskiem piłkarskim lub skórką od banana? W takim przypadku musimy zebrać wspólne właściwości tej rzeczy w konstrukcję, która może definiować właściwości obiektu - interfejs:

interfejs IThingWithLength {
  length: number;
}

Możemy użyć IThingWithLength jako typ interfejsu rzecz parametr:

function getLength(thing: IThingWithLength):number {
    return thing.length;
}

Szczerze mówiąc, w tym prostym przykładzie będzie to całkowicie w porządku, ale jeśli chcemy zachować ten typ generyczny i nie napotkać problemu z pierwszego przykładu, możemy użyć Ogólne ograniczenia:

function getLength(thing: T):number {
    return thing.length;
}

i używać go:

interfejs IBananaPeel {
  grubość: liczba;
  długość: liczba;
}

const bananaPeel: IBananaPeel = {grubość: 0.2, długość: 3.14};
getLength(bananaPeel);

Korzystanie z rozciąga się zapewnia, że T będzie zawierać właściwości zdefiniowane przez IThingWithLength.

Klasy ogólne

Do tego momentu pracowaliśmy z funkcjami generycznymi, ale nie jest to jedyne miejsce, w którym generics błyszczą, zobaczmy, jak możemy je włączyć do klas.

Najpierw spróbujmy przechować kiść bananów w koszyku z bananami:

class Banana {
  konstruktor(
    public długość: liczba,
    public color: string,
    public ionizingRadiation: liczba
  ) {}
}

class BananaBasket {
  private bananas: Banana[] = [];

  add(banana: Banana): void {
    this.bananas.push(banana);
  }
}

const bananaBasket = new BananaBasket();
bananaBasket.add(new Banana(3.14, 'red', 10e-7));

Teraz spróbujmy stworzyć koszyk ogólnego przeznaczenia, do różnych rzeczy tego samego typu:

class Basket {
  private stuff: T[] = [];

  add(thing: T): void {
    this.stuff.push(thing);
  }
}

const bananaBasket = new Basket();

I na koniec, załóżmy, że nasz kosz jest pojemnikiem na materiały radioaktywne i możemy przechowywać tylko materię, która ma promieniowanie jonizujące nieruchomości:

interfejs IRadioactive {
  ionizingRadiation: number;
}

class RadioactiveContainer {
  private stuff: T[] = [];

  add(thing: T): void {
    this.stuff.push(thing);
  }
}

Interfejs ogólny

Na koniec spróbujmy zebrać całą naszą wiedzę i zbudować radioaktywne imperium również przy użyciu Generic Interfaces:

// Definiowanie wspólnych atrybutów dla kontenerów
interfejs IRadioactive {
  ionizingRadiation: number;
}


// Definiuje coś, co jest radioaktywne
interface IBanana extends IRadioactive {
  długość: liczba;
  color: string;
}

// Zdefiniuj coś, co nie jest radioaktywne
interfejs IDog {
  weight: number;
}

// Zdefiniuj interfejs dla kontenera, który może przechowywać tylko radioaktywne rzeczy
interface IRadioactiveContainer {
  add(thing: T): void;
  getRadioactiveness():number;
}

// Zdefiniuj klasę implementującą interfejs kontenera radioaktywnego
class RadioactiveContainer implements IRadioactiveContainer {
  private stuff: T[] = [];

  add(thing: T): void {
    this.stuff.push(thing);
  }

  getRadioactiveness(): number {
      return this.stuff.reduce((a, b) => a + b.ionizingRadiation, 0)
  }
}

// BŁĄD! Typ "IDog" nie spełnia ograniczenia "IRadioactive
// I to jest trochę brutalne, aby przechowywać psy wewnątrz radioaktywnego kontenera
const dogsContainer = new RadioactiveContainer();

// Wszystko w porządku fam!
const radioactiveContainer = new RadioactiveContainer();

// Pamiętaj o sortowaniu odpadów radioaktywnych - utwórz osobny pojemnik tylko na banany
const bananasContainer = new RadioactiveContainer();

To wszystko!

Powiązane artykuły

Software Development

Tworzenie przyszłościowych aplikacji internetowych: spostrzeżenia zespołu ekspertów The Codest

Odkryj, w jaki sposób The Codest wyróżnia się w tworzeniu skalowalnych, interaktywnych aplikacji internetowych przy użyciu najnowocześniejszych technologii, zapewniając płynne doświadczenia użytkowników na wszystkich platformach. Dowiedz się, w jaki sposób nasza wiedza napędza transformację cyfrową i biznes...

THEECODEST
Software Development

10 najlepszych firm tworzących oprogramowanie na Łotwie

Dowiedz się więcej o najlepszych łotewskich firmach programistycznych i ich innowacyjnych rozwiązaniach w naszym najnowszym artykule. Odkryj, w jaki sposób ci liderzy technologiczni mogą pomóc w rozwoju Twojej firmy.

thecodest
Rozwiązania dla przedsiębiorstw i scaleupów

Podstawy tworzenia oprogramowania Java: Przewodnik po skutecznym outsourcingu

Zapoznaj się z tym niezbędnym przewodnikiem na temat skutecznego tworzenia oprogramowania Java outsourcing, aby zwiększyć wydajność, uzyskać dostęp do wiedzy specjalistycznej i osiągnąć sukces projektu z The Codest.

thecodest
Software Development

Kompletny przewodnik po outsourcingu w Polsce

Wzrost liczby outsourcing w Polsce jest napędzany przez postęp gospodarczy, edukacyjny i technologiczny, sprzyjający rozwojowi IT i przyjazny klimat dla biznesu.

TheCodest
Rozwiązania dla przedsiębiorstw i scaleupów

Kompletny przewodnik po narzędziach i technikach audytu IT

Audyty IT zapewniają bezpieczne, wydajne i zgodne z przepisami systemy. Dowiedz się więcej o ich znaczeniu, czytając cały artykuł.

The Codest
Jakub Jakubowicz CTO & Współzałożyciel

Subskrybuj naszą bazę wiedzy i bądź na bieżąco!

    O nas

    The Codest - Międzynarodowa firma programistyczna z centrami technologicznymi w Polsce.

    Wielka Brytania - siedziba główna

    • Office 303B, 182-184 High Street North E6 2JA
      Londyn, Anglia

    Polska - lokalne centra technologiczne

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warszawa, Polska

      The Codest

    • Strona główna
    • O nas
    • Nasze Usługi
    • Case Studies
    • Nasze Know How
    • Kariera
    • Słownik

      Nasze Usługi

    • Konsultacje IT
    • Software Development
    • Backend Development
    • Frontend Development
    • Zespoły IT
    • Backend Dev
    • Inżynierowie rozwiązań chmurowych
    • Inżynierowie danych
    • Inne
    • Inżynierowie QA

      Raporty

    • Fakty i mity na temat współpracy z zewnętrznym partnerem programistycznym
    • Z USA do Europy: Dlaczego amerykańskie startupy decydują się na relokację do Europy?
    • Porównanie centrów rozwoju Tech Offshore: Tech Offshore Europa (Polska), ASEAN (Filipiny), Eurazja (Turcja)
    • Jakie są największe wyzwania CTO i CIO?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Warunki korzystania z witryny

    Copyright © 2025 by The Codest. Wszelkie prawa zastrzeżone.

    pl_PLPolish
    en_USEnglish de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek pl_PLPolish