Hulpprogrammatypen in TypeScript
Dit artikel legt hulpprogrammatypen in TypeScript uit.
YouTube Video
Hulpprogrammatypen in TypeScript
Hulpprogrammatypen in TypeScript zijn handige hulpmiddelen om nieuwe typen te maken op basis van bestaande typen. Dit zorgt voor flexibelere typeringsdefinities en verhoogt de herbruikbaarheid van code. Hier zullen we veelgebruikte hulpprogrammatypen in detail uitleggen en bespreken hoe je elk type kunt gebruiken met voorbeeldcode.
Partial<T>
Partial<T>
maakt alle eigenschappen van een objecttype optioneel (waarbij undefined
is toegestaan). Het is handig wanneer je slechts enkele eigenschappen van het oorspronkelijke type wilt gebruiken.
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'
- In het bovenstaande voorbeeld maakt het gebruik van
Partial<User>
alle eigenschappen van het typeUser
optioneel. Daarom kun je in de functieupdateUser
slechts een deelverzameling van de eigenschappen doorgeven.
Required<T>
Required<T>
maakt alle eigenschappen, inclusief optionele, verplicht. Het wordt gebruikt wanneer je optionele eigenschappen verplicht wilt maken.
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 });
- Met
Required<User>
worden eigenschappen zoalsname
enage
als verplicht beschouwd.
Readonly<T>
Readonly<T>
maakt alle eigenschappen van een object alleen-lezen. Dit voorkomt dat de waarden van het object worden gewijzigd.
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);
- Met
Readonly<T>
kun je de eigenschappen van een object beschermen tegen wijzigingen. Het is effectief wanneer je wilt voorkomen dat gegevens per ongeluk worden gewijzigd tijdens de ontwikkeling.
Record<K, T>
Record<K, T>
maakt een kaarttype met gespecificeerde sleutel- en waarde-typen. K
is het type voor de sleutels (zoals string
of number
), en T
is het type voor de waarden.
1type Roles = "admin" | "user" | "guest";
2interface ReadWritePermissions {
3 read: boolean;
4 write: boolean;
5}
6
7const rolePermissions: Record<Roles, ReadWritePermissions> = {
8 admin: { read: true, write: true },
9 user: { read: true, write: false },
10 guest: { read: false, write: false },
11};
12
13console.log(rolePermissions);
Record<K, T>
is handig wanneer je sleutel-waardeparen wilt definiëren. In het bovenstaande voorbeeld worden machtigingen gedefinieerd op basis van gebruikersrollen.
Pick<T, K>
Pick<T, K>
haalt alleen gespecificeerde eigenschappen uit een objecttype. Je kunt een nieuw type maken door alleen de noodzakelijke eigenschappen te extraheren.
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);
- Met
Pick<T, K>
kun je specifieke eigenschappen uit een objecttype extraheren en ze als een nieuw type behandelen. In het bovenstaande voorbeeld worden bijvoorbeeld alleenid
enname
geëxtraheerd.
Omit<T, K>
Omit<T, K>
sluit specifieke eigenschappen uit van een objecttype. Dit is de tegenovergestelde bewerking van 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);
- Met
Omit<T, K>
kun je een nieuw type maken door gespecificeerde eigenschappen uit te sluiten. In het bovenstaande voorbeeld is de eigenschapemail
uitgesloten.
Exclude<T, U>
Exclude<T, U>
maakt een nieuw type door type U
te verwijderen uit unietype T
. Het wordt gebruikt wanneer je een specifiek type wilt verwijderen.
1type Status = "active" | "inactive" | "pending";
2type ExcludedStatus = Exclude<Status, "pending">;
3
4const userStatus: ExcludedStatus = "active"; // "pending" is excluded, so it cannot be chosen
5console.log(userStatus);
- Met
Exclude<T, U>
kun je onnodige types binnen een unietype verwijderen. In het bovenstaande voorbeeld, aangezien"pending"
is uitgesloten, kunnen alleen"active"
of"inactive"
worden geselecteerd.
Extract<T, U>
Extract<T, U>
haalt de delen op die overeenkomen met type U
binnen unietype T
. Het is handig wanneer je alleen een specifiek type wilt extraheren.
1type Status = "active" | "inactive" | "pending";
2type ActiveStatus = Extract<Status, "active" | "pending">;
3
4const userStatus: ActiveStatus = "active"; // "inactive" cannot be chosen
5console.log(userStatus);
Extract<T, U>
voert de tegenovergestelde bewerking vanExclude
uit. In het bovenstaande voorbeeld kunnen alleen"active"
en"pending"
worden geselecteerd.
NonNullable<T>
NonNullable<T>
maakt een type aan waarin null
en undefined
zijn uitgesloten. Het is nuttig wanneer je deze waarden wilt uitsluiten van optionele types.
1type UserName = string | null | undefined;
2type ValidUserName = NonNullable<UserName>;
3
4const userName: ValidUserName = "Alice"; // null and undefined cannot be chosen
5console.log(userName);
- NietNullable
.
Conclusie
TypeScript utility types zijn krachtige hulpmiddelen om type-definities beknopter en flexibeler te maken. Het begrijpen en juist gebruiken van basis utility types zoals Partial
, Required
, Readonly
, Record
, enz., kan de herbruikbaarheid en onderhoudbaarheid van code verbeteren. Het beheersen van deze types zorgt voor robuustere en veiligere type-definities, waardoor efficiënte ontwikkeling mogelijk wordt.
De keyof
-operator in TypeScript
De keyof
-operator in TypeScript wordt gebruikt om alle eigenschapsnamen van een objecttype op te halen. Met deze operator kun je de sleutels van een objecttype verkrijgen als een union type. Dit is uiterst nuttig voor het schrijven van type-safe code.
Basisgebruik
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"
Voorbeeldgebruik
Gebruik ervan in Functieargumenten
Je kunt keyof
gebruiken om een functie te definiëren met typen gebaseerd op specifieke eigenschappen van een object.
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 userName = getProperty(person, "name"); // type is string
7const age = getProperty(person, "age"); // type is number
8
9console.log("Name:", userName);
10console.log("Age:", age);
- Deze functie haalt een eigenschap op van een object op een typeveilige manier op basis van de opgegeven sleutel.
Typebeperkingen Versterken
Door keyof
te gebruiken, kun je ervoor zorgen dat de sleutels die aan een functie worden doorgegeven tijdens de compilatie worden gevalideerd.
1// Passing an invalid property name results in an error
2const invalid = getProperty(person, "invalidKey"); // Error
- Deze code toont aan dat het specificeren van een niet-bestaande eigenschap zal resulteren in een compile-time fout.
Samenvatting
- De
keyof
-operator wordt gebruikt om alle eigenschapsnamen van een objecttype op te halen. - Je kunt de eigenschapsnamen als een union type verkrijgen, waarmee je type-safe code bereikt.
- Door het te gebruiken in functieargumenten kun je de functie beperken tot het accepteren van alleen geldige eigenschapsnamen.
Op deze manier versterkt de keyof
-operator de typestriktheid in TypeScript en helpt hij je robuustere code te schrijven.
Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.