Utility-typer i TypeScript
Denne artikel forklarer utility-typer i TypeScript.
YouTube Video
Utility-typer i TypeScript
TypeScript utility-typer er praktiske værktøjer til at skabe nye typer baseret på eksisterende typer. Dette tillader mere fleksible typedefinitioner og øger genanvendeligheden af koden. Her vil vi forklare almindeligt anvendte utility-typer i detaljer og diskutere, hvordan man bruger hver enkelt med eksempler på kode.
Partial<T>
Partial<T>
gør alle egenskaber af en objekttype valgfrie (tillader undefined
). Det er nyttigt, når du kun vil bruge nogle af de egenskaber, som den originale type har.
1interface User {
2 id: number;
3 name: string;
4 age: number;
5}
6
7function updateUser(user: Partial<User>) {
8 console.log(user);
9}
10
11updateUser({ name: "Alice" }); // Updates only 'name'
Forklaring:
I eksemplet ovenfor gør brugen af Partial<User>
alle egenskaber af typen User
valgfrie. Derfor kan du i updateUser
-funktionen kun videregive et underudvalg af egenskaberne.
Required<T>
Required<T>
gør alle egenskaber, inklusive de valgfrie, obligatoriske. Det bruges, når du vil ændre egenskaber, der er valgfrie, til at være obligatoriske.
1interface User {
2 id: number;
3 name?: string;
4 age?: number;
5}
6
7function createUser(user: Required<User>) {
8 console.log(user);
9}
10
11// createUser({ id: 1 }); // Error: 'name' and 'age' are required
12createUser({ id: 1, name: "Alice", age: 25 });
Forklaring:
Ved at bruge Required<User>
behandles egenskaber som name
og age
som obligatoriske.
Readonly<T>
Readonly<T>
gør alle egenskaber af et objekt skrivebeskyttede. Dette forhindrer, at værdierne i objektet ændres.
1interface User {
2 id: number;
3 name: string;
4}
5
6const user: Readonly<User> = {
7 id: 1,
8 name: "Alice"
9};
10
11// user.id = 2; // Error: 'id' is read-only
12console.log(user);
Forklaring:
Ved at bruge Readonly<T>
kan du beskytte et objekts egenskaber mod at blive ændret. Det er effektivt, når du vil forhindre, at data utilsigtet ændres under udvikling.
Record<K, T>
Record<K, T>
skaber en map-type med specificerede nøgle- og værdityper. K
er typen for nøglerne (såsom string
eller number
), og T
er typen for værdierne.
1type Roles = "admin" | "user" | "guest";
2interface Permissions {
3 read: boolean;
4 write: boolean;
5}
6
7const rolePermissions: Record<Roles, Permissions> = {
8 admin: { read: true, write: true },
9 user: { read: true, write: false },
10 guest: { read: false, write: false },
11};
12
13console.log(rolePermissions);
Forklaring:
Record<K, T>
er nyttigt, når du vil definere nøgle-værdi-par. I eksemplet ovenfor defineres tilladelser baseret på brugerroller.
Pick<T, K>
Pick<T, K>
udtrækker kun specificerede egenskaber fra en objekttype. Du kan skabe en ny type ved kun at udtrække de nødvendige egenskaber.
1interface User {
2 id: number;
3 name: string;
4 age: number;
5}
6
7type UserSummary = Pick<User, "id" | "name">;
8
9const summary: UserSummary = {
10 id: 1,
11 name: "Alice"
12};
13
14console.log(summary);
Forklaring:
Ved at bruge Pick<T, K>
kan du udtrække specifikke egenskaber fra en objekttype og behandle dem som en ny type. For eksempel udtrækkes kun id
og name
i eksemplet ovenfor.
Omit<T, K>
Omit<T, K>
udelader angivne egenskaber fra en objekttype. Dette er den modsatte operation af Pick
.
1interface User {
2 id: number;
3 name: string;
4 age: number;
5 email: string;
6}
7
8type UserWithoutEmail = Omit<User, "email">;
9
10const userWithoutEmail: UserWithoutEmail = {
11 id: 1,
12 name: "Alice",
13 age: 25
14};
15
16console.log(userWithoutEmail);
Forklaring:
Ved at bruge Omit<T, K>
kan du skabe en ny type ved at udelade angivne egenskaber. I eksemplet ovenfor er email
-egenskaben udeladt.
Exclude<T, U>
Exclude<T, U>
skaber en ny type ved at fjerne type U
fra unionstypen T
. Det bruges, når du ønsker at fjerne en bestemt type.
1type Status = "active" | "inactive" | "pending";
2type ExcludedStatus = Exclude<Status, "pending">;
3
4const status: ExcludedStatus = "active"; // "pending" is excluded, so it cannot be chosen
5console.log(status);
Forklaring:
Ved at bruge Exclude<T, U>
kan du fjerne unødvendige typer inden for en unionstype. I eksemplet ovenfor, da "pending"
er udeladt, kan kun "active"
eller "inactive"
vælges.
Extract<T, U>
Extract<T, U>
udtrækker de dele, der matcher type U
inden for unionstypen T
. Det er nyttigt, når du vil udtrække kun en specifik type.
1type Status = "active" | "inactive" | "pending";
2type ActiveStatus = Extract<Status, "active" | "pending">;
3
4const status: ActiveStatus = "active"; // "inactive" cannot be chosen
5console.log(status);
Forklaring:
Extract<T, U>
udfører den modsatte operation af Exclude
. I eksemplet ovenfor kan kun "active"
og "pending"
vælges.
NonNullable<T>
NonNullable<T>
skaber en type, hvor null
og undefined
er udeladt. Det er nyttigt, når du vil udelade disse værdier fra valgfrie typer.
1type UserName = string | null | undefined;
2type ValidUserName = NonNullable<UserName>;
3
4const name: ValidUserName = "Alice"; // null and undefined cannot be chosen
5console.log(name);
Forklaring:
NonNullable<T>
udelader null
og undefined
fra en type, der indeholder dem. Dette er nyttigt, når du vil sikre, at en værdi bestemt findes.
Konklusion
TypeScripts utility-typer er kraftfulde værktøjer til at gøre typedefinitioner mere koncise og fleksible. At forstå og korrekt bruge grundlæggende utility-typer som Partial
, Required
, Readonly
, Record
osv., kan forbedre kodens genanvendelighed og vedligeholdelse. At mestre disse typer muliggør mere robuste og sikre typedefinitioner, der fremmer effektiv udvikling.
TypeScripts keyof
-operator
TypeScripts keyof
-operator bruges til at hente alle egenskabsnavne for en objekttype. Ved at bruge denne operator kan du opnå nøglerne af en objekttype som en unionstype. Dette er ekstremt nyttigt til at skrive typesikkert kode.
Grundlæggende Brug
1interface Person {
2 name: string;
3 age: number;
4 email: string;
5}
6
7// Use keyof to get the property names of Person
8type PersonKeys = keyof Person; // "name" | "age" | "email"
Eksempel på brug
-
Brug i Funktionsargumenter
Du kan bruge
keyof
til at definere en funktion, der har typer baseret på specifikke egenskaber for et objekt.
1function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
2 return obj[key];
3}
4
5const person: Person = { name: "Alice", age: 30, email: "alice@example.com" };
6const name = getProperty(person, "name"); // type is string
7const age = getProperty(person, "age"); // type is number
-
Forbedring af Typebegrænsninger
Ved at bruge
keyof
kan du sikre, at de nøgler, der sendes til en funktion, valideres ved kompileringstidspunktet.
1// Passing an invalid property name results in an error
2const invalid = getProperty(person, "invalidKey"); // Error
Sammendrag
keyof
-operatoren bruges til at hente alle egenskabsnavne for en objekttype.- Du kan opnå egenskabsnavnene som en unionstype og dermed opnå typesikkert kode.
- Ved at bruge den i funktionsargumenter kan du begrænse funktionen til kun at acceptere gyldige egenskabsnavne.
På denne måde forbedrer keyof
-operatoren typesikkerheden i TypeScript og hjælper dig med at skrive mere robust kode.
Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.