Generics i TypeScript
Denne artikkelen forklarer generics i TypeScript.
YouTube Video
Generics i TypeScript
Generics i TypeScript er en funksjon som lar deg definere gjenbrukbare og typesikre funksjoner, klasser og grensesnitt ved å parameterisere typer. Ved å bruke generics kan du skrive kode som ikke er avhengig av spesifikke typer, og dermed utføre de samme operasjonene på ulike typer.
Grunnleggende om Generics
Generics fungerer som maler som aksepterer typer som argumenter, og gjør det mulig for funksjoner og klasser å håndtere ulike typer.
Generiske Funksjoner
Følgende er et eksempel på en funksjon der argumenttypene er angitt ved hjelp av generics.
1function identity<T>(value: T): T {
2 return value;
3}
4
5console.log(identity<number>(42)); // 42
6console.log(identity<string>("Hello")); // Hello
T
er et generisk typeargument som representerer typene til funksjonens argumenter og returverdi. Den faktiske typen bestemmes når funksjonen kalles.- Ved eksplisitt å spesifisere
<number>
eller<string>
, spesifiserer du typen.
Generiske typer fungerer uten eksplisitt spesifikasjon fordi TypeScript utfører typeinferens.
1function identity<T>(value: T): T {
2 return value;
3}
4
5console.log(identity(42)); // 42
6console.log(identity("Hello")); // Hello
Begrensninger på Generics
Ved å legge begrensninger på generics kan du begrense dem til å akseptere kun spesifikke typer.
1function loggingIdentity<T extends { length: number }>(arg: T): T {
2 console.log(arg.length);
3 return arg;
4}
5
6loggingIdentity("Hello"); // 5
7loggingIdentity([1, 2, 3]); // 3
8
9// loggingIdentity(42); // Error: number does not have a length property.
- Å spesifisere
T extends { length: number }
indikerer atT
må være en type med enlength
-egenskap. Dermed vil typer uten enlength
-egenskap ikke bli akseptert.
Generiske Klasser
Klasser kan også defineres ved hjelp av generics. Generiske klasser gir fleksible typer for egenskaper og metoder.
1class Box<T> {
2 private _value: T;
3
4 constructor(value: T) {
5 this._value = value;
6 }
7
8 public getValue(): T {
9 return this._value;
10 }
11
12 public setValue(value: T): void {
13 this._value = value;
14 }
15}
16
17const numberBox = new Box<number>(100);
18console.log(numberBox.getValue()); // 100
19
20const stringBox = new Box<string>("Hello");
21console.log(stringBox.getValue()); // Hello
Box<T>
erklærer typenT
brukt i klassen som en generic. Dette gjør at samme klasse kan brukes om igjen for forskjellige typer.
Generiske Grensesnitt
Generics kan også brukes med grensesnitt.
1interface Pair<T, U> {
2 first: T;
3 second: U;
4}
5
6const numberStringPair: Pair<number, string> = { first: 1, second: "One" };
7console.log(numberStringPair); // { first: 1, second: 'One' }
8
9const booleanArrayPair: Pair<boolean, number[]> = { first: true, second: [1, 2, 3] };
10console.log(booleanArrayPair); // { first: true, second: [ 1, 2, 3 ] }
- Ved å spesifisere to generiske typer med
Pair<T, U>
, kan du definere et objekt med en kombinasjon av ulike typer.
Standardtypargumenter
Det er også mulig å spesifisere en standardtype for generiske typeargumenter.
1function createArray<T = string>(length: number, value: T): T[] {
2 return Array(length).fill(value);
3}
4
5console.log(createArray(3, "a")); // ['a', 'a', 'a']
6console.log(createArray(3, 100)); // [100, 100, 100]
- Vi setter standardtypeargumentet til
string
med<T = string>
. Hvis ingen type er spesifisert eksplisitt, vilT
være av typenstring
.
Generiske typealiaser
Generiske typer kan også brukes som typealiaser (type
).
1type Result<T> = {
2 success: boolean;
3 data: T;
4};
5
6const successResult: Result<number> = { success: true, data: 42 };
7const errorResult: Result<string> = { success: false, data: "Error occurred" };
8
9console.log(successResult); // { success: true, data: 42 }
10console.log(errorResult); // { success: false, data: 'Error occurred' }
Result<T>
representerer et resultatobjekt som inneholder data av typenT
. På denne måten kan du lage fleksible typealiaser ved hjelp av generiske typer.
Flere generiske typer
Ved å bruke flere generiske typer kan du definere enda mer allsidige funksjoner og klasser.
1function merge<T, U>(obj1: T, obj2: U): T & U {
2 return { ...obj1, ...obj2 };
3}
4
5const person = { name: "Alice" };
6const job = { title: "Engineer" };
7
8const merged = merge(person, job);
9console.log(merged); // { name: 'Alice', title: 'Engineer' }
merge
-funksjonen tar to forskjellige typerT
ogU
og kombinerer dem for å returnere et nytt objekt.
Sammendrag
- Generics muliggjør gjenbrukbar og typesikker kode ved å behandle typer som parametere.
- Ved å bruke generiske typer i funksjoner, klasser og grensesnitt, kan du skrive fleksibel logikk som håndterer forskjellige typer.
- Ved å legge til begrensninger på typeargumenter eller sette standardtypeargumenter, kan du kontrollere omfanget av generiske typer.
Ved å bruke generiske typer kan du skrive typeuavhengig og generell kode, og utnytte TypeScripts kraftige typesystem fullt ut.
Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.