Eesti

Avastage TypeScript'i literaaltüüpe, mis jõustavad rangeid väärtuspiiranguid, parandavad koodi selgust ja ennetavad vigu. Õppige praktiliste näidete ja täiustatud tehnikatega.

TypeScript'i literaaltüübid: täpsete väärtuspiirangute valdamine

TypeScript, JavaScripti ülemhulk, toob staatilise tüüpimise veebiarenduse dünaamilisse maailma. Üks selle võimsamaid omadusi on literaaltüüpide kontseptsioon. Literaaltüübid võimaldavad teil määrata täpse väärtuse, mida muutuja või omadus võib hoida, pakkudes paremat tüübiohutust ja ennetades ootamatuid vigu. See artikkel uurib literaaltüüpe põhjalikult, käsitledes nende süntaksit, kasutamist ja eeliseid praktiliste näidete abil.

Mis on literaaltüübid?

Erinevalt traditsioonilistest tüüpidest nagu string, number või boolean, ei esinda literaaltüübid laia väärtuste kategooriat. Selle asemel esindavad nad konkreetseid, fikseeritud väärtusi. TypeScript toetab kolme tüüpi literaaltüüpe:

Kasutades literaaltüüpe, saate luua täpsemaid tüübimääratlusi, mis peegeldavad teie andmete tegelikke piiranguid, mis viib vastupidavama ja hooldatavama koodini.

Stringi literaaltüübid

Stringi literaaltüübid on kõige sagedamini kasutatav literaalide tüüp. Need võimaldavad teil määrata, et muutuja või omadus saab hoida ainult ühte eelmääratletud stringiväärtuste hulgast.

Põhisüntaks

Stringi literaaltüübi defineerimise süntaks on lihtne:


type AllowedValues = "value1" | "value2" | "value3";

See defineerib tüübi nimega AllowedValues, mis saab hoida ainult stringe "value1", "value2" või "value3".

Praktilised näited

1. Värvipaleti defineerimine:

Kujutage ette, et loote kasutajaliidese teeki ja soovite tagada, et kasutajad saaksid määrata ainult eelmääratletud paleti värve:


type Color = "red" | "green" | "blue" | "yellow";

function paintElement(element: HTMLElement, color: Color) {
  element.style.backgroundColor = color;
}

paintElement(document.getElementById("myElement")!, "red"); // Kehtiv
paintElement(document.getElementById("myElement")!, "purple"); // Viga: Tüübi '"purple"' argumenti ei saa määrata parameetrile tüübiga 'Color'.

See näide demonstreerib, kuidas stringi literaaltüübid saavad jõustada ranget lubatud väärtuste hulka, vältides arendajatel kehtetute värvide juhuslikku kasutamist.

2. API lõpp-punktide defineerimine:

API-dega töötades peate sageli määrama lubatud lõpp-punktid. Stringi literaaltüübid aitavad seda jõustada:


type APIEndpoint = "/users" | "/posts" | "/comments";

function fetchData(endpoint: APIEndpoint) {
  // ... implementatsioon andmete toomiseks määratud lõpp-punktist
  console.log(`Fetching data from ${endpoint}`);
}

fetchData("/users"); // Kehtiv
fetchData("/products"); // Viga: Tüübi '"/products"' argumenti ei saa määrata parameetrile tüübiga 'APIEndpoint'.

See näide tagab, et funktsiooni fetchData saab välja kutsuda ainult kehtivate API lõpp-punktidega, vähendades trükivigadest või valedest lõpp-punktide nimedest tulenevate vigade ohtu.

3. Erinevate keelte haldamine (rahvusvahelistamine - i18n):

Globaalsetes rakendustes peate võib-olla haldama erinevaid keeli. Saate kasutada stringi literaaltüüpe, et tagada, et teie rakendus toetab ainult määratud keeli:


type Language = "en" | "es" | "fr" | "de" | "zh";

function translate(text: string, language: Language): string {
  // ... implementatsioon teksti tõlkimiseks määratud keelde
  console.log(`Translating '${text}' to ${language}`);
  return "Translated text"; // Kohatäide
}

translate("Hello", "en"); // Kehtiv
translate("Hello", "ja"); // Viga: Tüübi '"ja"' argumenti ei saa määrata parameetrile tüübiga 'Language'.

See näide demonstreerib, kuidas tagada, et teie rakenduses kasutatakse ainult toetatud keeli.

Numbri literaaltüübid

Numbri literaaltüübid võimaldavad teil määrata, et muutuja või omadus saab hoida ainult konkreetset arvulist väärtust.

Põhisüntaks

Numbri literaaltüübi defineerimise süntaks sarnaneb stringi literaaltüüpidele:


type StatusCode = 200 | 404 | 500;

See defineerib tüübi nimega StatusCode, mis saab hoida ainult numbreid 200, 404 või 500.

Praktilised näited

1. HTTP olekukoodide defineerimine:

Saate kasutada numbri literaaltüüpe HTTP olekukoodide esitamiseks, tagades, et teie rakenduses kasutatakse ainult kehtivaid koode:


type HTTPStatus = 200 | 400 | 401 | 403 | 404 | 500;

function handleResponse(status: HTTPStatus) {
  switch (status) {
    case 200:
      console.log("Õnnestus!");
      break;
    case 400:
      console.log("Vigane päring");
      break;
    // ... teised juhud
    default:
      console.log("Tundmatu olek");
  }
}

handleResponse(200); // Kehtiv
handleResponse(600); // Viga: Tüübi '600' argumenti ei saa määrata parameetrile tüübiga 'HTTPStatus'.

See näide jõustab kehtivate HTTP olekukoodide kasutamist, vältides vigade tekkimist valede või mittestandardsete koodide kasutamisel.

2. Fikseeritud valikute esitamine:

Saate kasutada numbri literaaltüüpe fikseeritud valikute esitamiseks konfiguratsiooniobjektis:


type RetryAttempts = 1 | 3 | 5;

interface Config {
  retryAttempts: RetryAttempts;
}

const config1: Config = { retryAttempts: 3 }; // Kehtiv
const config2: Config = { retryAttempts: 7 }; // Viga: Tüüpi '{ retryAttempts: 7; }' ei saa määrata tüübile 'Config'.

See näide piirab retryAttempts võimalikke väärtusi konkreetse hulgaga, parandades teie konfiguratsiooni selgust ja usaldusväärsust.

Tõeväärtuse literaaltüübid

Tõeväärtuse literaaltüübid esindavad konkreetseid väärtusi true või false. Kuigi need võivad tunduda vähem mitmekülgsed kui stringi või numbri literaaltüübid, võivad need olla kasulikud konkreetsetes stsenaariumides.

Põhisüntaks

Tõeväärtuse literaaltüübi defineerimise süntaks on:


type IsEnabled = true | false;

Siiski on true | false otsekasutamine üleliigne, kuna see on samaväärne boolean tüübiga. Tõeväärtuse literaaltüübid on kasulikumad, kui neid kombineerida teiste tüüpidega või tingimuslikes tüüpides.

Praktilised näited

1. Tingimuslik loogika konfiguratsiooniga:

Saate kasutada tõeväärtuse literaaltüüpe, et kontrollida funktsiooni käitumist konfiguratsioonilipu alusel:


interface FeatureFlags {
  darkMode: boolean;
  newUserFlow: boolean;
}

function initializeApp(flags: FeatureFlags) {
  if (flags.darkMode) {
    // Lülita sisse tume režiim
    console.log("Tumeda režiimi sisselülitamine...");
  } else {
    // Kasuta heledat režiimi
    console.log("Heleda režiimi kasutamine...");
  }

  if (flags.newUserFlow) {
    // Lülita sisse uus kasutajavoog
    console.log("Uue kasutajavoo sisselülitamine...");
  } else {
    // Kasuta vana kasutajavoogu
    console.log("Vana kasutajavoo kasutamine...");
  }
}

initializeApp({ darkMode: true, newUserFlow: false });

Kuigi see näide kasutab standardset boolean tüüpi, võiksite seda kombineerida tingimuslike tüüpidega (selgitatakse hiljem), et luua keerukamat käitumist.

2. Diskrimineeritud ühendid (unions):

Tõeväärtuse literaaltüüpe saab kasutada diskriminaatoritena ühendtüüpides. Vaadake järgmist näidet:


interface SuccessResult {
  success: true;
  data: any;
}

interface ErrorResult {
  success: false;
  error: string;
}

type Result = SuccessResult | ErrorResult;

function processResult(result: Result) {
  if (result.success) {
    console.log("Õnnestumine:", result.data);
  } else {
    console.error("Viga:", result.error);
  }
}

processResult({ success: true, data: { name: "John" } });
processResult({ success: false, error: "Andmete toomine ebaõnnestus" });

Siin toimib success omadus, mis on tõeväärtuse literaaltüüp, diskriminaatorina, võimaldades TypeScriptil kitsendada result tüüpi if lause sees.

Literaaltüüpide kombineerimine ühendtüüpidega

Literaaltüübid on kõige võimsamad, kui neid kombineerida ühendtüüpidega (kasutades | operaatorit). See võimaldab teil defineerida tüübi, mis saab hoida ühte mitmest konkreetsest väärtusest.

Praktilised näited

1. Olekutüübi defineerimine:


type Status = "ootel" | "töös" | "lõpetatud" | "ebaõnnestunud";

interface Task {
  id: number;
  description: string;
  status: Status;
}

const task1: Task = { id: 1, description: "Logimise implementeerimine", status: "töös" }; // Kehtiv
const task2: Task = { id: 2, description: "Väljalogimise implementeerimine", status: "tehtud" };       // Viga: Tüüpi '{ id: number; description: string; status: string; }' ei saa määrata tüübile 'Task'.

See näide demonstreerib, kuidas jõustada konkreetset lubatud olekuväärtuste hulka Task objekti jaoks.

2. Seadmetüübi defineerimine:

Mobiilirakenduses peate võib-olla haldama erinevaid seadmetüüpe. Saate neid esitada stringi literaaltüüpide ühendiga:


type DeviceType = "mobiil" | "tahvel" | "töölaud";

function logDeviceType(device: DeviceType) {
  console.log(`Seadme tüüp: ${device}`);
}

logDeviceType("mobiil"); // Kehtiv
logDeviceType("smartwatch"); // Viga: Tüübi '"smartwatch"' argumenti ei saa määrata parameetrile tüübiga 'DeviceType'.

See näide tagab, et funktsiooni logDeviceType kutsutakse välja ainult kehtivate seadmetüüpidega.

Literaaltüübid tüübialiasega

Tüübialiased (kasutades type võtmesõna) annavad võimaluse anda literaaltüübile nimi, muutes teie koodi loetavamaks ja hooldatavamaks.

Praktilised näited

1. Valuutakoodi tüübi defineerimine:


type CurrencyCode = "USD" | "EUR" | "GBP" | "JPY";

function formatCurrency(amount: number, currency: CurrencyCode): string {
  // ... implementatsioon summa vormindamiseks vastavalt valuutakoodile
  console.log(`Vormindan ${amount} valuutas ${currency}`);
  return "Vormindatud summa"; // Kohatäide
}

formatCurrency(100, "USD"); // Kehtiv
formatCurrency(200, "CAD"); // Viga: Tüübi '"CAD"' argumenti ei saa määrata parameetrile tüübiga 'CurrencyCode'.

See näide defineerib CurrencyCode tüübialiase valuutakoodide hulgale, parandades formatCurrency funktsiooni loetavust.

2. Nädalapäeva tüübi defineerimine:


type DayOfWeek = "Esmaspäev" | "Teisipäev" | "Kolmapäev" | "Neljapäev" | "Reede" | "Laupäev" | "Pühapäev";

function isWeekend(day: DayOfWeek): boolean {
  return day === "Laupäev" || day === "Pühapäev";
}

console.log(isWeekend("Esmaspäev"));   // false
console.log(isWeekend("Laupäev")); // true
console.log(isWeekend("Funday"));   // Viga: Tüübi '"Funday"' argumenti ei saa määrata parameetrile tüübiga 'DayOfWeek'.

Literaalide tuletamine

TypeScript suudab sageli literaaltüüpe automaatselt tuletada muutujatele määratud väärtuste põhjal. See on eriti kasulik töötades const muutujatega.

Praktilised näited

1. Stringi literaaltüüpide tuletamine:


const apiKey = "your-api-key"; // TypeScript tuletab apiKey tüübiks "your-api-key"

function validateApiKey(key: "your-api-key") {
  return key === "your-api-key";
}

console.log(validateApiKey(apiKey)); // true

const anotherKey = "invalid-key";
console.log(validateApiKey(anotherKey)); // Viga: Tüübi 'string' argumenti ei saa määrata parameetrile tüübiga '"your-api-key"'.

Selles näites tuletab TypeScript apiKey tüübiks stringi literaaltüübi "your-api-key". Kui aga määrate muutujale mittekonstantse väärtuse, tuletab TypeScript tavaliselt laiema string tüübi.

2. Numbri literaaltüüpide tuletamine:


const port = 8080; // TypeScript tuletab pordi tüübiks 8080

function startServer(portNumber: 8080) {
  console.log(`Käivitan serveri pordil ${portNumber}`);
}

startServer(port); // Kehtiv

const anotherPort = 3000;
startServer(anotherPort); // Viga: Tüübi 'number' argumenti ei saa määrata parameetrile tüübiga '8080'.

Literaaltüüpide kasutamine tingimuslike tüüpidega

Literaaltüübid muutuvad veelgi võimsamaks, kui neid kombineerida tingimuslike tüüpidega. Tingimuslikud tüübid võimaldavad teil defineerida tüüpe, mis sõltuvad teistest tüüpidest, luues väga paindlikke ja väljendusrikkaid tüübisüsteeme.

Põhisüntaks

Tingimusliku tüübi süntaks on:


TypeA extends TypeB ? TypeC : TypeD

See tähendab: kui TypeA on määratav tüübile TypeB, siis on tulemuseks olev tüüp TypeC; vastasel juhul on tulemuseks olev tüüp TypeD.

Praktilised näited

1. Oleku vastavusse viimine sõnumiga:


type Status = "ootel" | "töös" | "lõpetatud" | "ebaõnnestunud";

type StatusMessage = T extends "ootel"
  ? "Ootel tegevusele"
  : T extends "töös"
  ? "Hetkel töös"
  : T extends "lõpetatud"
  ? "Ülesanne edukalt lõpetatud"
  : "Ilmnes viga";

function getStatusMessage(status: T): StatusMessage {
  switch (status) {
    case "ootel":
      return "Ootel tegevusele" as StatusMessage;
    case "töös":
      return "Hetkel töös" as StatusMessage;
    case "lõpetatud":
      return "Ülesanne edukalt lõpetatud" as StatusMessage;
    case "ebaõnnestunud":
      return "Ilmnes viga" as StatusMessage;
    default:
      throw new Error("Vigane olek");
  }
}

console.log(getStatusMessage("ootel"));    // Ootel tegevusele
console.log(getStatusMessage("töös")); // Hetkel töös
console.log(getStatusMessage("lõpetatud"));   // Ülesanne edukalt lõpetatud
console.log(getStatusMessage("ebaõnnestunud"));      // Ilmnes viga

See näide defineerib StatusMessage tüübi, mis seob iga võimaliku oleku vastava sõnumiga, kasutades tingimuslikke tüüpe. Funktsioon getStatusMessage kasutab seda tüüpi, et pakkuda tüübiohutuid olekusõnumeid.

2. Tüübiohutu sündmuste käsitleja loomine:


type EventType = "click" | "mouseover" | "keydown";

type EventData = T extends "click"
  ? { x: number; y: number; } // Klikisündmuse andmed
  : T extends "mouseover"
  ? { target: HTMLElement; }   // Hiirega üle minemise sündmuse andmed
  : { key: string; }             // Klahvivajutuse sündmuse andmed

function handleEvent(type: T, data: EventData) {
  console.log(`Käsitlen sündmuse tüüpi ${type} andmetega:`, data);
}

handleEvent("click", { x: 10, y: 20 }); // Kehtiv
handleEvent("mouseover", { target: document.getElementById("myElement")! }); // Kehtiv
handleEvent("keydown", { key: "Enter" }); // Kehtiv

handleEvent("click", { key: "Enter" }); // Viga: Tüübi '{ key: string; }' argumenti ei saa määrata parameetrile tüübiga '{ x: number; y: number; }'.

See näide loob EventData tüübi, mis defineerib erinevaid andmestruktuure vastavalt sündmuse tüübile. See võimaldab teil tagada, et igale sündmuse tüübile edastatakse funktsioonile handleEvent õiged andmed.

Literaaltüüpide kasutamise parimad praktikad

Et oma TypeScripti projektides literaaltüüpe tõhusalt kasutada, kaaluge järgmisi parimaid praktikaid:

Literaaltüüpide kasutamise eelised

Kokkuvõte

TypeScripti literaaltüübid on võimas funktsioon, mis võimaldab teil jõustada rangeid väärtuspiiranguid, parandada koodi selgust ja ennetada vigu. Mõistes nende süntaksit, kasutamist ja eeliseid, saate kasutada literaaltüüpe, et luua vastupidavamaid ja hooldatavamaid TypeScripti rakendusi. Alates värvipalettide ja API lõpp-punktide defineerimisest kuni erinevate keelte haldamise ja tüübiohutute sündmuste käsitlejate loomiseni pakuvad literaaltüübid laia valikut praktilisi rakendusi, mis võivad teie arendustöövoogu oluliselt täiustada.