crypto-community-spends-1-million-to-genoplive-elon-musk-inspired-token-floki-inu.jpg

Typescript type indsnævring

Kildeknude: 1857482

Mange gange skal vi være i stand til at skelne mellem Typescript-grænseflader, som har nogle egenskaber til fælles. Tag følgende eksempel:

interface Vehicle { weight: number; wheels?: number; class?: 'A' | '1' | '2' | '3';
}

I vores applikation har vi forskellige køretøjer. For lastbiler, for eksempel, ønsker vi at holde styr på deres vægt og deres antal hjul. Men andre køretøjer (såsom yatches) har ingen hjul, men har andre attributter, vi gerne vil vide, som for eksempel deres klasse, som er en streng, der kan tage værdierne 'A', '1', '2' eller '3' .

Vi tror måske, at en god konfiguration kan være som følger:

interface Truck { weight: number; wheels: number;
} interface Yatch { weight: number; class: 'A' | '1' | '2' | '3';
} export type Vehicle = Truck | Yatch;

Men med denne opsætning vil vi have et problem, når vi forsøger at bruge Vehicle objekter:

Som vi kan se, kan Typescript ikke afgøre, om inputobjektet er en Truck eller Yatch, og det kaster følgende fejl:

Property 'wheels' does not exist on type 'Yatch'

Hvordan kan vi indsnævre objektets type? Der er mindst 3 alternativer:

1. Opret en ny type egenskab på hver af grænsefladerne

interface Truck { weight: number; wheels: number; type: 'truck';
} interface Yatch { weight: number; class: 'A' | '1' | '2' | '3'; type: 'yatch';
} export type Vehicle = Truck | Yatch;

Dette er kendt som diskriminerede fagforeninger i maskinskrift. Denne løsning ville være den mest passende, hvis vores grænseflader allerede havde type egenskab på forhånd.

Når du bruger Vehicle objekter, nu kan vi bruge en switch case til at skelne mellem begge grænseflader:

Hvis vi bruger klasser i stedet for grænseflader til vores typer, giver følgende alternative syntaks nøjagtig samme resultat:

class Truck { weight: number; wheels: number; readonly type = 'truck';
} class Yatch { weight: number; class: 'A' | '1' | '2' | '3'; readonly type = 'yatch';
} export type Vehicle = Truck | Yatch;

2. Brug typeafskærmninger

Type vagter er funktioner, der hjælper med typeindsnævring.

interface Truck { weight: number; wheels: number;
} interface Yatch { weight: number; class: 'A' | '1' | '2' | '3';
} export type Vehicle = Truck | Yatch; export function isTruck(arg: any): arg is Truck { return !!arg.weight && !!arg.wheels;
} export function isYatch(arg: any): arg is Yatch { return !!arg.weight && !!arg.class;
}

If isTruck(object) afkast true, betyder det, at vores objekt faktisk er en Truck. Vi kan importere og bruge disse funktioner hvor som helst i vores applikation:

Der er dog et lille problem med denne opsætning: vi kan stadig bygge Vehicle genstande, der ikke er Truck heller ikke Yatch:

3. Brug "aldrig"

For at løse dette sidste problem kan vi bruge og never type, introduceret i Typescript 2.0. Hvis en grænseflade har en egenskab af typen never, så kan den egenskab ikke defineres på noget objekt, der følger efter denne grænseflade.

interface Truck { weight: number; wheels: number; class?: never;
} interface Yatch { weight: number; wheels?: never; class: 'A' | '1' | '2' | '3';
} export type Vehicle = Truck | Yatch;

Typevagter fungerer præcis, som de gjorde tidligere, men nu kan vi ikke oprette Vehicle genstande, som på samme tid har både den wheels , class ejendomme:

Som vi kan se, får vi følgende fejl:

Type 'number' is not assignable to type 'never'

Tjek den spanske version af dette indlæg på min blog cibetrucos.com

Kilde: https://www.codementor.io/davidsilvasanmartin/typescript-discriminated-unions-1jhqp24mvx

Tidsstempel:

Mere fra Kodementorfællesskab