Lietuvių

Tyrinėkite tipų apsaugas ir tvirtinimus TypeScript, kad padidintumėte tipų saugumą, išvengtumėte klaidų ir rašytumėte patikimesnį bei lengviau prižiūrimą kodą.

Tipų saugumo įvaldymas: išsamus tipų apsaugų ir tipų tvirtinimų vadovas

Programinės įrangos kūrimo srityje, ypač dirbant su dinamiškai tipizuojamomis kalbomis, tokiomis kaip JavaScript, išlaikyti tipų saugumą gali būti didelis iššūkis. TypeScript, JavaScript viršaibis, sprendžia šią problemą įvesdama statinį tipizavimą. Tačiau net ir su TypeScript tipų sistema atsiranda situacijų, kai kompiliatoriui reikia pagalbos nustatant teisingą kintamojo tipą. Būtent čia į pagalbą ateina tipų apsaugos (angl. type guards) ir tipų tvirtinimai (angl. type assertions). Šiame išsamiame vadove gilinsimės į šias galingas funkcijas, pateikdami praktinių pavyzdžių ir geriausių praktikų, siekiant pagerinti jūsų kodo patikimumą ir palaikomumą.

Kas yra tipų apsaugos?

Tipų apsaugos yra TypeScript išraiškos, kurios susiaurina kintamojo tipą tam tikroje apimtyje. Jos leidžia kompiliatoriui suprasti kintamojo tipą tiksliau, nei jis iš pradžių nustatė. Tai ypač naudinga dirbant su jungtiniais tipais (angl. union types) arba kai kintamojo tipas priklauso nuo vykdymo laiko sąlygų. Naudodami tipų apsaugas, galite išvengti vykdymo klaidų ir rašyti tvirtesnį kodą.

Įprastos tipų apsaugų technikos

TypeScript suteikia keletą integruotų mechanizmų tipų apsaugoms kurti:

typeof naudojimas

Operatorius typeof yra paprastas būdas patikrinti primityvųjį kintamojo tipą. Jis grąžina eilutę, nurodančią tipą.

function printValue(value: string | number) {
  if (typeof value === "string") {
    console.log(value.toUpperCase()); // TypeScript čia žino, kad 'value' yra eilutė
  } else {
    console.log(value.toFixed(2)); // TypeScript čia žino, kad 'value' yra skaičius
  }
}

printValue("hello"); // Išvestis: HELLO
printValue(3.14159); // Išvestis: 3.14

instanceof naudojimas

Operatorius instanceof tikrina, ar objektas yra tam tikros klasės egzempliorius. Tai ypač naudinga dirbant su paveldėjimu.

class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}

class Dog extends Animal {
  bark() {
    console.log("Woof!");
  }
}

function makeSound(animal: Animal) {
  if (animal instanceof Dog) {
    animal.bark(); // TypeScript čia žino, kad 'animal' yra Dog
  } else {
    console.log("Generic animal sound");
  }
}

const myDog = new Dog("Buddy");
const myAnimal = new Animal("Generic Animal");

makeSound(myDog); // Išvestis: Woof!
makeSound(myAnimal); // Išvestis: Generic animal sound

in naudojimas

Operatorius in tikrina, ar objektas turi tam tikrą savybę. Tai naudinga dirbant su objektais, kurie gali turėti skirtingas savybes priklausomai nuo jų tipo.

interface Bird {
  fly(): void;
  layEggs(): void;
}

interface Fish {
  swim(): void;
  layEggs(): void;
}

function move(animal: Bird | Fish) {
  if ("fly" in animal) {
    animal.fly(); // TypeScript čia žino, kad 'animal' yra Bird
  } else {
    animal.swim(); // TypeScript čia žino, kad 'animal' yra Fish
  }
}

const myBird: Bird = { fly: () => console.log("Flying"), layEggs: () => console.log("Laying eggs") };
const myFish: Fish = { swim: () => console.log("Swimming"), layEggs: () => console.log("Laying eggs") };

move(myBird); // Išvestis: Flying
move(myFish); // Išvestis: Swimming

Pasirinktinės tipų apsaugos funkcijos

Sudėtingesniems scenarijams galite apibrėžti savo tipų apsaugos funkcijas. Šios funkcijos grąžina tipo predikatą, kuris yra loginė išraiška, kurią TypeScript naudoja kintamojo tipui susiaurinti. Tipo predikatas turi formą kintamasis is Tipas.

interface Square {
  kind: "square";
  size: number;
}

interface Circle {
  kind: "circle";
  radius: number;
}

type Shape = Square | Circle;

function isSquare(shape: Shape): shape is Square {
  return shape.kind === "square";
}

function getArea(shape: Shape) {
  if (isSquare(shape)) {
    return shape.size * shape.size; // TypeScript čia žino, kad 'shape' yra Square
  } else {
    return Math.PI * shape.radius * shape.radius; // TypeScript čia žino, kad 'shape' yra Circle
  }
}

const mySquare: Square = { kind: "square", size: 5 };
const myCircle: Circle = { kind: "circle", radius: 3 };

console.log(getArea(mySquare)); // Išvestis: 25
console.log(getArea(myCircle)); // Išvestis: 28.274333882308138

Kas yra tipų tvirtinimai?

Tipų tvirtinimai yra būdas nurodyti TypeScript kompiliatoriui, kad jūs žinote daugiau apie kintamojo tipą, nei jis šiuo metu supranta. Tai būdas apeiti TypeScript tipo nustatymą ir aiškiai nurodyti reikšmės tipą. Tačiau svarbu naudoti tipų tvirtinimus atsargiai, nes jie gali apeiti TypeScript tipų tikrinimą ir, neteisingai panaudoti, gali sukelti vykdymo klaidų.

Tipų tvirtinimai turi dvi formas:

as raktažodis paprastai yra labiau pageidaujamas, nes yra suderinamesnis su JSX.

Kada naudoti tipų tvirtinimus

Tipų tvirtinimai paprastai naudojami šiais atvejais:

Tipų tvirtinimų pavyzdžiai

Aiškus tipo tvirtinimas

Šiame pavyzdyje mes tvirtiname, kad document.getElementById iškvietimas grąžins HTMLCanvasElement. Be tvirtinimo TypeScript nustatytų bendresnį tipą HTMLElement | null.

const canvas = document.getElementById("myCanvas") as HTMLCanvasElement;
const ctx = canvas.getContext("2d"); // TypeScript čia žino, kad 'canvas' yra HTMLCanvasElement

if (ctx) {
  ctx.fillStyle = "#FF0000";
  ctx.fillRect(0, 0, 150, 75);
}

Darbas su nežinomais tipais

Dirbant su duomenimis iš išorinio šaltinio, pavyzdžiui, API, galite gauti duomenis su nežinomu tipu. Galite naudoti tipo tvirtinimą, kad nurodytumėte TypeScript, kaip elgtis su duomenimis.

interface User {
  id: number;
  name: string;
  email: string;
}

async function fetchUser(id: number): Promise<User> {
  const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
  const data = await response.json();
  return data as User; // Patvirtiname, kad duomenys yra tipo User
}

fetchUser(1)
  .then(user => {
    console.log(user.name); // TypeScript čia žino, kad 'user' yra User
  })
  .catch(error => {
    console.error("Error fetching user:", error);
  });

Atsargumo priemonės naudojant tipų tvirtinimus

Tipų tvirtinimus reikia naudoti saikingai ir atsargiai. Pernelyg dažnas tipų tvirtinimų naudojimas gali paslėpti esamas tipų klaidas ir sukelti vykdymo problemų. Štai keletas svarbių aspektų:

Tipų siaurinimas

Tipų apsaugos yra neatsiejamai susijusios su tipų siaurinimo (angl. type narrowing) koncepcija. Tipų siaurinimas yra procesas, kurio metu kintamojo tipas patikslinamas iki konkretesnio tipo, atsižvelgiant į vykdymo laiko sąlygas ar patikrinimus. Tipų apsaugos yra įrankiai, kuriuos naudojame tipų siaurinimui pasiekti.

TypeScript naudoja valdymo srauto analizę, kad suprastų, kaip kintamojo tipas keičiasi skirtingose kodo šakose. Kai naudojama tipo apsauga, TypeScript atnaujina savo vidinį supratimą apie kintamojo tipą, leisdama saugiai naudoti metodus ir savybes, būdingus tam tipui.

Tipų siaurinimo pavyzdys

function processValue(value: string | number | null) {
  if (value === null) {
    console.log("Value is null");
  } else if (typeof value === "string") {
    console.log(value.toUpperCase()); // TypeScript čia žino, kad 'value' yra eilutė
  } else {
    console.log(value.toFixed(2)); // TypeScript čia žino, kad 'value' yra skaičius
  }
}

processValue("test"); // Išvestis: TEST
processValue(123.456); // Išvestis: 123.46
processValue(null); // Išvestis: Value is null

Geriausios praktikos

Norėdami efektyviai naudoti tipų apsaugas ir tipų tvirtinimus savo TypeScript projektuose, apsvarstykite šias geriausias praktikas:

Tarptautiniai aspektai

Kuriant programas pasaulinei auditorijai, atsižvelkite į tai, kaip tipų apsaugos ir tipų tvirtinimai gali paveikti lokalizavimo ir internacionalizavimo (i18n) pastangas. Ypač apsvarstykite:

Išvada

Tipų apsaugos ir tipų tvirtinimai yra esminiai įrankiai, skirti pagerinti tipų saugumą ir rašyti tvirtesnį TypeScript kodą. Suprasdami, kaip efektyviai naudoti šias funkcijas, galite išvengti vykdymo klaidų, pagerinti kodo palaikomumą ir kurti patikimesnes programas. Prisiminkite, kad kai tik įmanoma, teikite pirmenybę tipų apsaugoms, o ne tipų tvirtinimams, dokumentuokite savo tipų tvirtinimus ir patikrinkite išorinius duomenis, kad užtikrintumėte savo tipų informacijos tikslumą. Taikydami šiuos principus galėsite kurti stabilesnę ir labiau nuspėjamą programinę įrangą, tinkamą diegti visame pasaulyje.