Direct naar de hoofdinhoud
Module 5 · Les 1 van 29/14 in de cursus~15 min
Modulelessen (1/2)

Type bewakers

Typevernauwing is een van de belangrijkste concepten in TypeScript. Vaak zijn standaardbeveiligingen zoals typeof of instanceof echter niet voldoende voor complexe aangepaste objecten. Dit is waar Aangepaste Type Guards in beeld komen.

Standaard type bewakers

Laten we beginnen met een samenvatting van hoe TypeScript typen verkleint met behulp van standaard JavaScript-operatoren:

TS
function processInput(val: string | number) {
  if (typeof val === 'string') {
    // Here 'val' is of type string
    console.log(val.toUpperCase());
  } else {
    // Here 'val' is of type number
    console.log(val.toFixed(2));
  }
}

Aangepaste typebeschermers (operator is)

Om een ​​aangepaste typeguard te definiëren, maken we een functie die een typepredikaat retourneert in de indeling parameterName is Type in plaats van een standaard Booleaans retourtype.

De functie moet een Booleaanse waarde (true of false) retourneren. Als het true retourneert, weet TypeScript dat de doorgegeven parameter van het opgegeven type is.

TS
interface Cat {
  name: string;
  meow(): void;
}

interface Dog {
  name: string;
  bark(): void;
}

// This is a custom type guard
function isCat(animal: Cat | Dog): animal is Cat {
  return (animal as Cat).meow !== undefined;
}

function makeNoise(pet: Cat | Dog) {
  if (isCat(pet)) {
    // Here TypeScript knows 'pet' is a Cat
    pet.meow();
  } else {
    // Here TypeScript knows 'pet' is a Dog
    pet.bark();
  }
}

Veiligheid en werpen (as versus Type Guards)

Type casting (bijvoorbeeld val as Cat) dwingt de compiler om de ontwikkelaar te vertrouwen zonder enige echte runtime-verificatie. Als het runtime-object niet aan de verwachtingen voldoet, mislukt de code stil of genereert hij uitzonderingen.

Aangepaste typeguards voeren daarentegen een robuuste en dynamische runtimecontrole uit, waarbij ze de TypeScript-compiler veilig en nauwkeurig informeren over het werkelijke variabeletype:

TS
function processInput(input: unknown) {
  // unsafe casting: could crash if input does not have the split method
  // const str = input as string;
  // console.log(str.split(' '));

  // safe guard
  if (isString(input)) {
    console.log(input.split(' ')); // 100% Safe!
  }
}

Probeer het zelf

Oefening 1: Stringtype-bescherming

Oefening#ts.m5.l1.e1
Pogingen: 0Laden…

Maak een eenvoudige functie met de naam isString die fungeert als een aangepaste typebeschermer om te verifiëren of een onbekende waarde een tekenreeks is.

Editor laden…
Toon hint

Het retourtype van de functie moet val is string zijn, en je moet typeof gebruiken om te controleren of het gelijk is aan 'string'.

Oplossing beschikbaar na 3 pogingen

Oefening 2: Premium gebruikerstypebescherming

Oefening#ts.m5.l1.e2
Pogingen: 0Laden…

Gegeven de typen User en PremiumUser, schrijft u een type guard-functie isPremiumUser(user: User): user is PremiumUser die controleert of de gebruiker de 'premium'-rol heeft.

Editor laden…
Toon hint

Definieer de handtekening als functie isPremiumUser(user: User): gebruiker is PremiumUser en vergelijk user.role met 'premium'.

Oplossing beschikbaar na 3 pogingen

Oefening 3: Validatie van aangepaste foutobjecten

Oefening#ts.m5.l1.e3
Pogingen: 0Laden…

Implementeer de isCustomError(err: onbekend): err is de CustomError-functie die verifieert of een onbekende waarde een niet-null CustomError-object is dat de 'code'-sleutel bevat.

Editor laden…
Toon hint

Controleer eerst of het type fout 'object' is en niet nul, en gebruik vervolgens de operator 'in' om te controleren op de eigenschap 'code'.

Oplossing beschikbaar na 3 pogingen

Oefening 4: Beheerderstypewacht

Oefening#ts.m5.l1.e4
Pogingen: 0Laden…

Gegeven twee interfaces User (met eigenschapsrol: string) en Admin (uitbreiding van User en met een eigenschap adminToken: string), schrijf een type guard-functie met de naam isAdmin die een gebruiker van het type User accepteert en retourneert dat een type predikaatgebruiker Admin is. De bewaker moet controleren of de rol van de gebruiker gelijk is aan 'admin'.

Editor laden…
Toon hint

Definieer de handtekening als functie isAdmin(user: User): gebruiker is Admin en controleer of user.role === 'admin'.

Oplossing beschikbaar na 3 pogingen