Beste praksis i TypeScript-programmering

Beste praksis i TypeScript-programmering

Denne artikkelen forklarer beste praksis i TypeScript-programmering.

Denne guiden forklarer praktiske beste praksiser for å utnytte TypeScripts typer for å redusere feil og skrive mer lesbar kode.

YouTube Video

Beste praksis i TypeScript-programmering

Den største fordelen med TypeScript er 'å forhindre feil med typer og gjøre kodeintensjonen tydelig'.

Beste praksis er ikke bare regler, men et sett med prinsipper for å skrive sikker, lesbar og vedlikeholdbar kode. Nedenfor presenterer vi vanlige beste praksiser for TypeScript med praktiske eksempler.

Unngå any og gi alltid typer meningsfulle definisjoner

La oss først se på poenget med å ‘unngå any og bruke meningsfulle typer’.

any deaktiverer fullstendig typekontroll, noe som undergraver hensikten med å bruke TypeScript. I stedet for å bruke any bare for å få ting til å fungere, er det viktig å gi så beskrivende typer som mulig.

1// Bad
2function parse(data: any) {
3  return data.value;
4}

Denne koden kan akseptere hvilken som helst verdi, så kjøretidsfeil kan ikke forhindres.

1// Good
2type ParsedData = {
3  value: string;
4};
5
6function parse(data: ParsedData): string {
7  return data.value;
8}

Ved å definere typer tydeliggjør du hensikten med inn- og utdata og forbedrer sikkerheten.

Definer alltid objektstrukturer eksplisitt ved bruk av type eller interface.

La oss deretter se på poenget med å ‘alltid eksplisitt definere objektstrukturer ved å bruke type eller interface’.

Hvis du bruker objekter ad hoc, kan strukturen deres bli uklar. Trekk alltid ut typer for gjenbrukbarhet og vedlikeholdbarhet.

1// Bad
2function createUser(user: { name: string; age: number }) {
3  console.log(user.name);
4}

Selv i små kodebiter er det viktig å utvikle en vane med å separere typer.

1// Good
2type User = {
3  name: string;
4  age: number;
5};
6
7function createUser(user: User): void {
8  console.log(user.name);
9}

Ved å navngi typene blir det mye lettere å forstå hele kodebasen.

Bruk unionstyper for å representere alle mulige tilstander presist.

Hvis du bruker rå string- eller number-typer for betingelser, kan uforventede verdier snike seg forbi. Ved å bruke unionstyper kan du representere kun de tillatte tilstandene på typnivå.

1// Bad
2function setStatus(status: string) {
3  console.log(status);
4}

I denne koden kan meningsløse strenger eller feil verdier ikke oppdages ved kompileringstidspunktet.

1// Good
2type Status = "idle" | "loading" | "success" | "error";
3
4function setStatus(status: Status): void {
5  console.log(status);
6}

Ved å bruke unionstyper kan du pålitelig eliminere 'umulige tilstander' ved kompileringstidspunktet. Som et resultat vil sikkerheten i betingede grener og påliteligheten til koden bli forbedret.

Håndter null og undefined eksplisitt.

La oss så se på poenget med å ‘eksplisitt håndtere null og undefined’.

I TypeScript er det viktig å uttrykke mulig fravær av en verdi i typen. Hvis du holder ting uklare, kan det føre til kjøretidsfeil.

1type User = {
2  name: string;
3  email?: string;
4};

email eksisterer kanskje ikke, så du bør forholde deg til det.

1function printEmail(user: User): void {
2  if (user.email) {
3    console.log(user.email);
4  }
5}

Sjekk alltid valgfrie verdier før de brukes.

Bruk typeantakelser (as) kun som siste utvei.

La oss nå se på poenget med å ‘ikke misbruke type-assertions’.

Typepåstander omgår midlertidig TypeScript sin typekontroll for å erklære: 'Jeg vet at denne verdien har denne typen.'. Overforbruk av dem undergraver typesikkerheten.

1// Bad
2const value = input as string;

I denne koden oppstår det ingen feil selv om den faktiske verdien ikke er en streng, noe som kan forårsake kjøretidsfeil. Som vist i følgende kode, velg å sjekke sikkert ved å bruke type guards først.

1// Good
2function isString(value: unknown): value is string {
3  return typeof value === "string";
4}
5
6if (isString(input)) {
7  console.log(input.toUpperCase());
8}

Type guards er en mekanisme for å trygt bestemme en type ved å sjekke den faktiske verdien. Ved å prioritere type guards fremfor typepåstander, kan du enklere forhindre kjøretidsfeil.

Stol ikke for mye på typeinferens for returtyper.

La oss se på poenget med å ‘ikke stole for mye på typeinferering for returtyper’.

TypeScripts typeinferens er kraftig, men det er tryggere å eksplisitt annotere returtypene til offentlige funksjoner. Dette minimerer den potensielle virkningen av fremtidige endringer.

1// Bad
2function sum(a: number, b: number) {
3  return a + b;
4}

Uttal hensikten din tydelig selv i små funksjoner.

1// Good
2function sum(a: number, b: number): number {
3  return a + b;
4}

Å skrive ut returtyper øker stabiliteten til API-et ditt.

Håndter inndata sikkert ved å bruke unknown.

La oss se på poenget med å ‘trygt akseptere ekstern input ved å bruke unknown’.

For ekstern input som API-er, JSON eller brukerinput, bruk unknown i stedet for any. Ved å gjøre dette sikrer du at alle verdier blir validert, og opprettholder typesikkerhet.

1// Bad
2function handleResponse(data: any) {
3  console.log(data.id);
4}

Slik validerer du typer med unknown.

 1// Good
 2function handleResponse(data: unknown): void {
 3  if (
 4    typeof data === "object" &&
 5    data !== null &&
 6    "id" in data
 7  ) {
 8    console.log((data as { id: number }).id);
 9  }
10}

unknown kan ikke brukes som den er; det er en type som krever validering. Det er spesielt effektivt når du håndterer ekstern input.

Øk uttrykksevnen ved å kombinere små typer.

La oss se på poenget med å ‘øke uttrykksevnen ved å kombinere små typer’.

Å definere store typer på én gang reduserer lesbarhet og vedlikeholdbarhet. Del opp typene dine i meningsfulle enheter og kombiner dem ved behov.

 1type Id = number;
 2
 3type UserProfile = {
 4  id: Id;
 5  name: string;
 6};
 7
 8type UserWithStatus = UserProfile & {
 9  status: "active" | "inactive";
10};

Å behandle typer som komponenter hjelper til med å organisere designet ditt.

type og interface

Fordeler med interface

type og interface kan begge definere typer, men deres tiltenkte bruksområder og egenskaper er ulike. Ved å bruke dem til riktige formål blir hensikten med typedefinisjonene dine klarere.

 1// Bad
 2type User = {
 3  id: number;
 4  name: string;
 5};
 6
 7type AdminUser = {
 8  id: number;
 9  name: string;
10  role: "admin";
11};

Hvis du dupliserer fellesdeler på denne måten, blir koden din sårbar for endringer.

1// Good
2interface User {
3  id: number;
4  name: string;
5}
6
7interface AdminUser extends User {
8  role: "admin";
9}

interface er ideell for design som involverer utvidelse (extends) og passer best for å uttrykke 'formen' til objekter.

Fordeler med type

På den andre siden er type mer uttrykksfull og egnet for å håndtere unions- og skjærings-typer.

1// Good
2type Status = "idle" | "loading" | "success" | "error";
3
4type ApiResponse<T> =
5  | { status: "success"; data: T }
6  | { status: "error"; message: string };

type passer godt for å uttrykke tilstander, alternativer og kombinasjoner.

Retningslinjer for å velge mellom type og interface

Som tommelfingerregel bør du bruke interface for objektstrukturer og kontrakter, og type når du trenger uttrykksevnen til union, skjæringspunkt eller typeoperasjoner.

Begge fungerer på lignende måte, men det er viktig å velge ut fra hva som best kommuniserer hvorfor typen eksisterer.

Behandle typene dine som dokumentasjon.

Til slutt, la oss se på poenget med å ‘skrive typer som dokumentasjon’.

Gode typedefinisjoner formidler mer informasjon enn kommentarer noen gang kan. Det er viktig å sikte mot en tilstand der ‘spesifikasjonen kan forstås bare ved å se på typene’.

1type ApiError = {
2  code: number;
3  message: string;
4  retryable: boolean;
5};

På denne måten er en av TypeScripts store styrker at typedefinisjoner kan fungere som en slags spesifikasjonsdokumentasjon.

Sammendrag

TypeScript beste praksis handler ikke om å være altfor streng. Essensen er å tydeliggjøre hensikt gjennom typer og skrive kode som er robust mot endringer.

Ved å samle opp små regler i det daglige utviklingsarbeidet kan du oppnå langsiktige effekter som 'enklere kodegjennomganger', 'færre feil' og 'bedre forståelse for deg selv og andre i fremtiden.'.

Først, ved å tenke 'hvordan kan jeg uttrykke dette med typer?', vil du skrive kode av høy kvalitet i TypeScript-stil.

Du kan følge med på artikkelen ovenfor ved å bruke Visual Studio Code på vår YouTube-kanal. Vennligst sjekk ut YouTube-kanalen.

YouTube Video