TypeScript voor beginners, deel 5 Generics

De tweede zelfstudie in onze serie TypeScript voor beginners richtte zich op de basistypen die beschikbaar zijn in TypeScript. Met de typecontrole in TypeScript kunnen we ervoor zorgen dat aan de variabelen in onze code alleen specifieke soorten waarden kunnen worden toegewezen. Op deze manier kunnen we veel fouten vermijden tijdens het schrijven van code, omdat de IDE ons kan vertellen wanneer we een bewerking uitvoeren op een type dat het niet ondersteunt. Dit maakt het controleren van het type een van de beste kenmerken van TypeScript.

In deze zelfstudie concentreren we ons op een ander belangrijk kenmerk van deze taalgeneraties. Met generieke codes kunt u met TypeScript code schrijven die op verschillende gegevenstypen kan werken in plaats van te worden beperkt tot één enkele. U zult in detail leren over de behoefte aan generieke geneesmiddelen en hoe dit beter is dan alleen het gebruik van de ieder gegevenstype beschikbaar in TypeScript.

De behoefte aan generieke geneesmiddelen

Als u niet bekend bent met generieke geneesmiddelen, vraagt ​​u zich misschien af ​​waarom we ze überhaupt nodig hebben. In deze sectie zal ik deze vraag voor u beantwoorden. Laten we beginnen met het schrijven van een functie die een willekeurig element uit een reeks getallen zal terugsturen.

functie randomIntElem (theArray: number []): number let randomIndex = Math.floor (Math.random () * theArray.length); return theArray [randomIndex];  let posities: nummer [] = [103, 458, 472, 458]; let randomPosition: number = randomIntElem (positions);

De randomElem functie die we zojuist hebben gedefinieerd, neemt een array van getallen als zijn enige parameter. Het retourtype van de functie is ook als een getal opgegeven. We gebruiken de Math.random () functie om een ​​drijvende-komma willekeurig getal tussen 0 en 1 te retourneren. Vermenigvuldig het met de lengte van een gegeven reeks en roep Math.floor () op het resultaat geeft ons een willekeurige index. Zodra we de willekeurige index hebben, geven we het element terug bij die specifieke index.

Enige tijd later, laten we zeggen dat je een willekeurig stringelement uit een array van strings moet halen. Op dit punt kunt u besluiten een andere functie te maken die specifiek op strings is gericht.

function randomStrElem (theArray: string []): string let randomIndex = Math.floor (Math.random () * theArray.length); return theArray [randomIndex];  laat kleuren: string [] = ['violet', 'indigo', 'blauw', 'groen']; laat randomColor: string = randomStrElem (kleuren);

Wat als u een willekeurig element moet selecteren uit een matrix van een interface die u hebt gedefinieerd? Elke keer dat u een willekeurig element uit een array van verschillende soorten objecten wilt ophalen, is het niet haalbaar om een ​​nieuwe functie te maken.

Een oplossing voor dit probleem is het instellen van het type arrayparameter dat wordt doorgegeven aan de functies als ieder[]. Op deze manier kunt u uw functie slechts één keer schrijven en deze zal met een reeks van alle typen werken.

functie randomElem (theArray: any []): any let randomIndex = Math.floor (Math.random () * theArray.length); return theArray [randomIndex];  laat posities = [103, 458, 472, 458]; laat randomPosition = randomElem (posities); laat kleuren = ['violet', 'indigo', 'blauw', 'groen']; laat randomColor = randomElem (kleuren);

Zoals je kunt zien, kunnen we de bovenstaande functie gebruiken om willekeurige posities en willekeurige kleuren te krijgen. Een groot probleem met deze oplossing is dat u de informatie verliest over het type waarde dat wordt geretourneerd. 

Eerder waren we zeker van dat randomPosition zou een nummer zijn en willekeurige kleur zou een reeks zijn. Dit heeft ons geholpen deze waarden dienovereenkomstig te gebruiken. Alles wat we nu weten is dat het geretourneerde element van elk type kan zijn. In de bovenstaande code kunnen we het type opgeven willekeurige kleur een ... zijn aantal en krijg nog steeds geen foutmelding.

// Deze code compileert zonder een fout. laat kleuren: string [] = ['violet', 'indigo', 'blauw', 'groen']; laat randomColor: number = randomElem (kleuren);

Een betere oplossing om codeduplicatie te voorkomen en tegelijkertijd de typegegevens te behouden, is het gebruik van generieke geneesmiddelen. Hier is een generieke functie die willekeurige elementen uit een array retourneert.

functie randomElem(theArray: T []): T let randomIndex = Math.floor (Math.random () * theArray.length); return theArray [randomIndex];  laat kleuren: string [] = ['violet', 'indigo', 'blauw', 'groen']; laat randomColor: string = randomElem (kleuren);

Nu krijg ik een foutmelding als ik het type probeer te veranderen willekeurige kleur van draad naar aantal. Dit bewijst dat het gebruik van generieke geneesmiddelen een stuk veiliger is dan het gebruik van de ieder typ in dergelijke situaties.

Het gebruik van Generics kan zeer beperkend lijken

In de vorige sectie is besproken hoe u generieke functies kunt gebruiken in plaats van de ieder typ om een ​​enkele functie te schrijven en vermijd het opofferen van de voordelen van typecontrole. Een probleem met de generieke functie die we in de vorige sectie hebben geschreven, is dat TypeScript ons niet veel bewerkingen laat uitvoeren op de variabelen die eraan worden doorgegeven. 

Dit komt omdat TypeScript geen aannames kan doen over het type variabele dat van tevoren zal worden doorgegeven aan onze generieke functie. Als gevolg hiervan kan onze generieke functie alleen die bewerkingen gebruiken die van toepassing zijn op alle gegevenstypen. Het volgende voorbeeld moet dit concept verduidelijken.

function removeChar (theString: string, theChar: string): string let theRegex = new RegExp (theChar, "gi"); return theString.replace (theRegex, ");

Met de bovenstaande functie worden alle exemplaren van het opgegeven teken uit de gegeven reeks verwijderd. Misschien wilt u een generieke versie van deze functie maken, zodat u ook specifieke cijfers van een bepaald nummer en tekens uit een tekenreeks kunt verwijderen. Hier is de bijbehorende generieke functie.

functie removeIt(theInput: T, theIt: string): T let theRegex = new RegExp (theIt, "gi"); return theInput.replace (theRegex, ");

De removeChar functie liet je geen fout zien. Als u echter gebruikt vervangen binnen Verwijder het,TypeScript zal u dat vertellen vervangen bestaat niet voor type 'T'. Dit komt omdat TypeScript dat niet langer kan aannemen theInput wordt een tekenreeks.

Deze beperking van het gebruik van verschillende methoden in een generieke functie kan ertoe leiden dat u denkt dat het concept van generieke geneesmiddelen toch niet echt van pas komt. Er is niet echt veel dat u kunt doen met een handvol methoden die toepasbaar moeten zijn op alle gegevenstypen zodat u ze kunt gebruiken binnen een generieke functie.

Een belangrijk ding dat je op dit moment moet onthouden, is dat je over het algemeen geen functies hoeft te maken die met allerlei gegevenstypes worden gebruikt. Het is gebruikelijker om een ​​functie te maken die wordt gebruikt met een specifieke set of een reeks gegevenstypen. Deze beperking voor gegevenstypen maakt algemene functies veel nuttiger.

Generieke functies maken met beperkingen

De generieke Verwijder het functie uit de vorige sectie toonde een fout omdat de vervangen methode erin is bedoeld om te worden gebruikt met tekenreeksen, terwijl de parameters die daaraan worden doorgegeven, elk gegevenstype kunnen hebben. 

U kunt de strekt sleutelwoord om de gegevenstypen te beperken die worden doorgegeven aan een generieke functie in TypeScript. Echter, strekt is beperkt tot alleen interfaces en klassen. Dit betekent dat de meeste generieke functies die u maakt parameters hebben die een basisinterface of klasse uitbreiden. 

Hier is een generieke functie die de naam van mensen, familieleden of beroemdheden die eraan zijn doorgegeven, afdrukt.

interface People naam: string interface Familie naam: string, leeftijd: aantal, relatie: string interface Celebrity extends People profession: string functie printName(theInput: T): void console.log ('Mijn naam is $ theInput.name');  let serena: Celebrity = naam: 'Serena Williams', beroep: 'Tennisser' printName (serena);

In het bovenstaande voorbeeld hebben we drie interfaces gedefinieerd en elk ervan heeft een naam eigendom. De generieke print naam functie die we hebben gemaakt, accepteert elk object dat zich uitstrekt Mensen. Met andere woorden, u kunt een familie- of beroemdheidsobject doorgeven aan deze functie en de naam wordt zonder enige klacht afgedrukt. U kunt veel meer interfaces definiëren, en zo lang ze een naam eigenschap, kunt u de print naam functioneren zonder enig probleem.

Dit was een heel eenvoudig voorbeeld, maar je kunt wel meer nuttige generieke functies maken als je eenmaal vertrouwd bent met het hele proces. U kunt bijvoorbeeld een generieke functie maken die de totale waarde berekent van verschillende items die in een bepaalde maand worden verkocht, zolang elk item een ​​algemene waarde heeft. prijs eigendom om de prijs op te slaan en een uitverkocht eigenschap die het aantal verkochte items opslaat. Als u generieke gegevens gebruikt, kunt u dezelfde functie gebruiken zolang de items dezelfde interface of klasse uitbreiden.

Laatste gedachten

In deze zelfstudie heb ik geprobeerd de basisbeginselen van generieke teksten in TypeScript op een beginnersvriendelijke manier te behandelen. We begonnen het artikel door te praten over de behoefte aan generieke geneesmiddelen. Daarna leerden we over de juiste manier om generieke geneesmiddelen te gebruiken om codeduplicatie te voorkomen zonder de typecontrole te verliezen. Zodra u de basisbeginselen begrijpt die hier worden besproken, kunt u meer lezen over generieke geneesmiddelen in de officiële documentatie.

Als je vragen hebt over deze tutorial, zal ik ze graag beantwoorden in de comments.