TypeScript betingede typer

Betingede typer i TypeScript gir en måte å lage typer som avhenger av en betingelse. De gir mulighet for større fleksibilitet og uttrykksfullhet i typedefinisjoner, noe som gjør det mulig å modellere komplekse typeforhold på en klar og konsis måte. Denne artikkelen utforsker hvordan betingede typer fungerer i TypeScript og gir eksempler for å illustrere bruken av dem.

Hva er betingede typer?

Betingede typer gjør det mulig å lage typer som velges basert på en betingelse. De ligner på betingede utsagn i programmering, men fungerer på typenivå. Den grunnleggende syntaksen for en betinget type er:

type ConditionalType = T extends U ? X : Y;

I denne syntaksen:

  • T er typen som kontrolleres.
  • U er typen å sammenligne mot.
  • X er typen som returneres hvis T utvider U.
  • Y er typen som returneres hvis T ikke utvider U.

Grunnleggende eksempel på betingede typer

Her er et enkelt eksempel på en betinget type som returnerer forskjellige typer basert på om en gitt type er en streng eller ikke:

type IsString = T extends string ? "String" : "Not a string";

type Result1 = IsString;  // Result1 is "String"
type Result2 = IsString;  // Result2 is "Not a string"

I dette eksemplet sjekker IsString om T utvider string. Hvis den gjør det, er resultatet "String"; ellers er det "Not a string".

Bruke betingede typer med generiske typer

Betingede typer kan også brukes med generiske typer for å lage mer fleksible og gjenbrukbare typedefinisjoner. For eksempel, en type som trekker ut returtypen til en funksjon:

type ReturnType = T extends (...args: any[]) => infer R ? R : never;

type FunctionType = (x: number) => string;

type Result = ReturnType;  // Result is string

I dette eksemplet bruker ReturnType nøkkelordet infer for å utlede returtypen R av funksjonstypen T. Hvis T er en funksjonstype, vil ReturnType være returtypen; ellers er den standard til aldri.

Betingede typer med unionstyper

Betingede typer kan også fungere med fagforeningstyper for å håndtere flere mulige typer. For eksempel å skille mellom forskjellige fagforeningsmedlemmer:

type ExtractString = T extends string ? T : never;

type UnionType = string | number | boolean;

type Result = ExtractString;  // Result is string

I dette eksemplet trekker ExtractString ut string fra en unionstype UnionType, noe som resulterer i string.

Betingede typer med typetilordninger

Betingede typer kan kombineres med typetilordninger for å lage mer komplekse typetransformasjoner. For eksempel, tilordning over en rekke typer for å bruke en betinget type:

type MapArray = {
  [K in keyof T]: T[K] extends string ? T[K] : never;
};

type ArrayType = [string, number, boolean];

type MappedArray = MapArray;  // MappedArray is [string, never, never]

I dette eksemplet tilordner MapArray hvert element i matrisen T og bruker en betinget type på hvert element, noe som resulterer i en matrise der bare strengelementer er bevart.

Konklusjon

Betingede typer i TypeScript er et kraftig verktøy for å lage fleksible og uttrykksfulle typedefinisjoner. Ved å utnytte betingede typer kan utviklere modellere komplekse typeforhold, håndtere ulike scenarier og forbedre typesikkerheten i TypeScript-koden. Å forstå hvordan man bruker betingede typer effektivt kan forbedre muligheten til å skrive robust og vedlikeholdbar TypeScript-kode betydelig.