TypeScript Advanced Generics forklart med eksempler
Generikk i TypeScript gir en måte å lage gjenbrukbare og fleksible kodekomponenter ved å jobbe med en rekke datatyper. Avansert generikk tar dette konseptet videre ved å introdusere tilleggsfunksjoner som begrensninger, standardverdier og flere typer, som lar utviklere skrive mer robust og typesikker kode. I denne artikkelen vil eksempler bli brukt for å utforske disse avanserte konseptene i generikk.
Generiske begrensninger
Begrensninger begrenser typene som en generisk kan akseptere. Dette sikrer at typen som sendes til en generisk funksjon eller klasse oppfyller visse kriterier. For eksempel kan en begrensning brukes for å sikre at den generiske typen har en spesifikk egenskap eller metode.
function getLength<T extends { length: number }>(arg: T): number {
return arg.length;
}
const stringLength = getLength("TypeScript");
const arrayLength = getLength([1, 2, 3]);
I dette eksemplet sikrer <T extends { length: number }>
-begrensningen at argumentet som sendes til getLength
har en length
-egenskap.
Flere generiske
TypeScript tillater bruk av flere generiske typer i samme funksjon, klasse eller grensesnitt. Dette er nyttig når du arbeider med verdipar eller andre datastrukturer som involverer flere typer.
function pair<T, U>(first: T, second: U): [T, U] {
return [first, second];
}
const stringNumberPair = pair("TypeScript", 2024);
Denne funksjonen, par
, godtar to forskjellige generiske typer, T
og U
, og returnerer en tuppel som inneholder begge typene.
Standard generiske typer
Generikk i TypeScript kan også ha standardtyper. Dette er nyttig når du vil at en generisk type skal ha en reservetype hvis ingen spesifikk type er oppgitt.
function identity<T = string>(value: T): T {
return value;
}
const defaultString = identity("Hello"); // T is string
const customNumber = identity<number>(100); // T is number
I dette eksemplet, hvis ingen type sendes til identitet
, er den standard til streng
.
Bruke generiske med grensesnitt
Generikk kan brukes med grensesnitt for å definere komplekse strukturer der typer ikke er faste. Dette gir fleksibilitet til hvordan data administreres.
interface Container<T> {
value: T;
}
const stringContainer: Container<string> = { value: "Hello" };
const numberContainer: Container<number> = { value: 42 };
Container
-grensesnittet er designet for å holde en verdi av enhver type, noe som tillater forskjellige typer beholdere med spesifikke typer.
Generiske klasser
Klasser i TypeScript kan også være generiske. Dette er spesielt nyttig når du designer klasser som fungerer med ulike datatyper, for eksempel datalagring eller innsamlingsklasser.
class DataStore<T> {
private data: T[] = [];
add(item: T): void {
this.data.push(item);
}
getAll(): T[] {
return this.data;
}
}
const stringStore = new DataStore<string>();
stringStore.add("Hello");
stringStore.add("TypeScript");
const numberStore = new DataStore<number>();
numberStore.add(42);
I dette eksemplet fungerer DataStore
-klassen med alle typer data, og gir en typesikker måte å lagre og hente elementer på.
Konklusjon
Avansert generikk i TypeScript er et kraftig verktøy for å skrive fleksibel, gjenbrukbar og typesikker kode. Ved å bruke begrensninger, flere typer, standardverdier og generikk i klasser og grensesnitt, kan utviklere skrive mer kompleks og robust kode. Å forstå og bruke disse avanserte konseptene gir større fleksibilitet og sikrer typesikkerhet på tvers av applikasjoner.