След два месеца работа с TypeScript самостоятелното навигиране в неговите грешки може да не е голяма задача за мен. Въпреки това, колкото повече се задълбочаваме в TS, толкова по-лесно се оплитаме. Ето малко пояснение, което да ви помогне.

Разлики между:

  1. Енуми срещу константни енуми

Енумите са основни за ограничаване на използването на конкретни числови или низови данни, а не за твърдения за тип. Но за обикновени Enums той все още предоставя комбинация от както стойност, така и типименно пространство и също така може да преобразува в JavaScript обекти, които имат обратно съпоставяне. Например, при даден enum enum ExampleEnum { A = 0, B = 1 }, можете да получите достъп до ExampleEnum[0] и да получите стойността на низа "A" или да получите достъп до ExampleEnum["A"] и да получите числовата стойност 0.

enum DayOfWeek {
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday,
  Sunday,
}

const today: DayOfWeek = DayOfWeek.Monday;
const tmr: DayOfWeek = DayOfWeek.notMyday; // return false

2. Интерфейс срещу тип

По принцип те са еднакви, но за най-добра практика използвайте Тип за псевдоним на прост типе по-лесно. Например:

  1. Тип съюз:
type Status = "pending" | "inProgress" | "completed";

const currentStatus: Status = "inProgress"; // valid
// const currentStatus: Status = "error"; // invalid, as "error" is not part of the union type

2. Кортеж:

type Point = [number, number];

const coordinates: Point = [10, 20]; // valid
// const coordinates: Point = [10, 20, 30]; // invalid, as the tuple should have exactly two elements

3. Примитивни типове:

type MyNumber = number;
type MyString = string;
type MyBoolean = boolean;

const myAge: MyNumber = 30; // valid
const myName: MyString = "John"; // valid
const isStudent: MyBoolean = true; // valid

4. Картографиран тип:

type Flags = {
  [key: string]: boolean;
};

const settings: Flags = {
  darkMode: true,
  notifications: false,
  autoSave: true,
};

Интерфейсът осигурява повече гъвкавост при използване и позволява по-добра композиция и разширение при работа със сложни обектни форми.

interface Animal {
  name: string;
  type: "land" | "sea";
}

// Same interface name 'Animal' with additional properties for a specific type of animal
interface Animal {
  habitat?: string; // Optional property for land animals
  depth?: number;   // Optional property for sea animals
}

// Create objects based on the extended 'Animal' interface
const lion: Animal = {
  name: "Lion",
  type: "land",
  habitat: "savannah",
};

const dolphin: Animal = {
  name: "Dolphin",
  type: "sea",
  depth: 200,
};

// Function that accepts an 'Animal' object and prints its details
function printAnimalDetails(animal: Animal) {
  console.log(`Name: ${animal.name}`);
  console.log(`Type: ${animal.type}`);

  // Additional properties based on the type of animal
  if (animal.type === "land" && animal.habitat) {
    console.log(`Habitat: ${animal.habitat}`);
  } else if (animal.type === "sea" && animal.depth) {
    console.log(`Depth: ${animal.depth}`);
  }
}

// Print details of the animals
printAnimalDetails(lion);
printAnimalDetails(dolphin);

3. keyof срещу typeof

keyof се фокусира единствено върху получаване на ключове на обекти, typeof се концентрира върху определяне на типове променливи, докато интерфейсите предоставят цялостно решение, като обхващат както структурата на обекта, така и ключовете.

//keyOf example

interface Person {
  name: string;
  age: number;
  city: string;
}

type PersonKeys = keyof Person;
// The above line is equivalent to:
// type PersonKeys = "name" | "age" | "city"

function getProperty<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

const person: Person = {
  name: "John",
  age: 30,
  city: "New York",
};

const name = getProperty(person, "name"); // Valid, name is of type string
const age = getProperty(person, "age"); // Valid, age is of type number
const city = getProperty(person, "city"); // Valid, city is of type string
const invalidKey = getProperty(person, "gender"); // Error, "gender" is not a key of Person

4. Празнота срещу никога

void се използва за функции, които не връщат стойност, докато never се използва за функции, които никога не връщат или завършват поради изключителни сценарии.

function throwError(message: string): never {
  throw new Error(message);
}

function logMessage(message: string): void {
  console.log(message);
}

5. Всеки срещу неизвестен

Всички знаем всеки! Най-разрешителният тип в TypeScript, който ни пречи да напуснем използването на TS. JK, unknown предоставя по-безопасна алтернатива на any, като ви принуждава да обработвате изрично проверките на типа, докато any позволява непроверен достъп до всяка стойност, жертвайки безопасността на типа. Обикновено се препоръчва да се използва unknown вместо any, когато се работи с неизвестни или смесени стойности.

let userInput: unknown;

// Type check before using the variable
if (typeof userInput === "string") {
  console.log(userInput.toUpperCase());
} else {
  console.log("Input is not a string.");
}