Sådan pakker du hovedet rundt i Generelt af typen Script

Foto af Hannah Wei på Unsplash

Et stykke tid tilbage, da debatten "Flow vs. Typescript" rasede, var jeg nødt til at vælge en side. Og jeg valgte Typescript. Heldigvis var det en af ​​de bedre beslutninger, jeg tog. Da jeg var nødt til at tage denne beslutning, var det, der i sidste ende overbeviste mig, Typerips støtte til generik af opkaldstid.

I dag, lad mig prøve at lede dig igennem, hvad generiske resultater opnår, og hvordan det hjælper os med at skrive en mere sikker, renere og mere vedligeholdelig kode.

Eksempel 1: Påvisning af en enkel type

Lad os sige, at vi har brug for en funktion, der tager enhver værdi og sætter den ind i et objekt. En naiv implementering af dette i Typescript ville se ud og køre sådan:

Så meget for typesikkerhed.

Det er rigtigt, at myValue kan være af enhver art. Men hvad vi er nødt til at fortælle controlleren, er, at output af funktionen, selvom den ikke kan forudses som udvikleren, der skriver koden, kan "udledes" af typen af ​​inputtype. Med andre ord kan vi have en "generisk definition" af, hvad output er.

Generisk implementering af ovennævnte funktion ville være noget som dette:

Det, vi blot siger, er, at myValue kan have en type T. Det kan være ”enhver type”, men ikke nogen type. Med andre ord, det har en type, vi holder af.

Hvis du prøver at skrive den tidligere udførelse i Typescript, kan du ikke køre den, da kompilatoren giver en nyttig advarsel:

Eksempel 2: Skrivning af idx med Generics

idx er et "Bibliotek til adgang til vilkårligt indlejrede, muligvis nullable egenskaber på et JavaScript-objekt". Det er især nyttigt, når du arbejder med komplekse Javascript-objekter som REST API-svar, der kan have nullable felter.

Hvis du ikke har noget imod mig at forenkle dette lidt, udfører det dette ved dybest set at prøve den funktion, der er givet som den anden parameter med rekvisitter. Hvis det mislykkes, fanger det og returnerer en udefineret værdi sikkert uden at kaste.

Igen ville en naiv implementering af dette være:

Men hvis vi er lidt kloge med generik, kan vi få Typescript til at hjælpe os med dette.

Vi har introduceret to generika her.

T for inputtypen, og vi "antyder", at det er et objekt ved at sige T udvider {}. U er for udgangstypen. Og med disse kan vi udtrykke, at vælgerfunktionen er noget, der tager T og returnerer U for udefineret.

Hvis du nu forsøger at skrive den samme kode som før med denne definition af idx, får du en kompilationsfejl:

Eksempel nr. 3: Brug af type inferens og generika for at få returneret type af en funktion

Antag, at jeg har en funktion, og jeg er nødt til at forsyne forbrugeren med typen af ​​output. Hvis jeg kalder denne type FooOutput, skriver jeg noget som:

Men ved at bruge generiske egenskaber og type inferencer, kan jeg skrive en generisk type ReturnType, der kan "udlede" returtypen for en funktion:

Vi spiller med en T-udvidelse (... args: any []) => hvilken som helst her. Dette betyder bare, at T er en generisk funktionstype, der tager ethvert antal af argumenter og producerer en værdi. Derefter bruger vi det til at udlede en anden type R og returnere den.

Ved hjælp af dette undgår jeg behovet for at skrive min returtype i ovenstående eksempel manuelt. Da foo er en funktion, og jeg har brug for den funktionstype for at bruge ReturnType, skal jeg hente typen foo ved at bruge typeof.

Nyttige værktøjer i min værktøjskasse 🛠

Jeg bruger en masse af disse hjælpeprogrammer til daglig programmering. De fleste af generationsværktøjerne er defineret i typeskriptet lib.es5.d.ts herover. Nogle af mine mest anvendte inkluderer:

Forhåbentlig hjælper dette dig med at forstå typeskriptgeneriske ting mere. Hvis du har spørgsmål, tøv ikke med at give et spørgsmål nedenunder.