Українська

Розкрийте можливості const-стверджень у TypeScript для виведення незмінних типів, підвищуючи безпеку та передбачуваність коду у ваших проєктах. Дізнайтеся, як ефективно їх використовувати на практичних прикладах.

Const-ствердження в TypeScript: виведення незмінних типів для надійного коду

TypeScript, надмножина JavaScript, привносить статичну типізацію у динамічний світ веброзробки. Однією з його потужних особливостей є виведення типів, коли компілятор автоматично визначає тип змінної. Const-ствердження, представлені в TypeScript 3.4, виводять виведення типів на новий рівень, дозволяючи вам забезпечувати імутабельність та створювати більш надійний і передбачуваний код.

Що таке const-ствердження?

Const-ствердження — це спосіб повідомити компілятору TypeScript, що ви маєте намір зробити значення незмінним. Вони застосовуються за допомогою синтаксису as const після літерального значення або виразу. Це вказує компілятору вивести найвужчий можливий (літеральний) тип для виразу та позначити всі властивості як readonly.

По суті, const-ствердження забезпечують вищий рівень безпеки типів, ніж просте оголошення змінної за допомогою const. Хоча const запобігає перепризначенню самої змінної, воно не забороняє змінювати об'єкт або масив, на який посилається змінна. Const-ствердження запобігають також і зміні властивостей об'єкта.

Переваги використання const-стверджень

Практичні приклади

Приклад 1: Базове використання з літералом

Без const-ствердження TypeScript виводить тип message як string:


const message = "Hello, World!"; // Тип: string

З const-ствердженням TypeScript виводить тип як літеральний рядок "Hello, World!":


const message = "Hello, World!" as const; // Тип: "Hello, World!"

Це дозволяє використовувати літеральний тип рядка в більш точних визначеннях типів та порівняннях.

Приклад 2: Використання const-стверджень з масивами

Розглянемо масив кольорів:


const colors = ["red", "green", "blue"]; // Тип: string[]

Незважаючи на те, що масив оголошений за допомогою const, ви все ще можете змінювати його елементи:


colors[0] = "purple"; // Без помилки
console.log(colors); // Вивід: ["purple", "green", "blue"]

Додавши const-ствердження, TypeScript виводить тип масиву як кортеж рядків тільки для читання:


const colors = ["red", "green", "blue"] as const; // Тип: readonly ["red", "green", "blue"]

Тепер спроба змінити масив призведе до помилки TypeScript:


// colors[0] = "purple"; // Помилка: Індексна сигнатура в типі 'readonly ["red", "green", "blue"]' дозволяє лише читання.

Це гарантує, що масив colors залишається незмінним.

Приклад 3: Використання const-стверджень з об'єктами

Подібно до масивів, об'єкти також можна зробити незмінними за допомогою const-стверджень:


const person = {
  name: "Alice",
  age: 30,
}; // Тип: { name: string; age: number; }

Навіть з const ви все ще можете змінювати властивості об'єкта person:


person.age = 31; // Без помилки
console.log(person); // Вивід: { name: "Alice", age: 31 }

Додавання const-ствердження робить властивості об'єкта readonly:


const person = {
  name: "Alice",
  age: 30,
} as const; // Тип: { readonly name: "Alice"; readonly age: 30; }

Тепер спроба змінити об'єкт призведе до помилки TypeScript:


// person.age = 31; // Помилка: Неможливо присвоїти 'age', оскільки це властивість тільки для читання.

Приклад 4: Використання const-стверджень із вкладеними об'єктами та масивами

Const-ствердження можна застосовувати до вкладених об'єктів та масивів для створення глибоко незмінних структур даних. Розглянемо наступний приклад:


const config = {
  apiUrl: "https://api.example.com",
  endpoints: {
    users: "/users",
    products: "/products",
  },
  supportedLanguages: ["en", "fr", "de"],
} as const;

// Тип:
// {
//   readonly apiUrl: "https://api.example.com";
//   readonly endpoints: {
//     readonly users: "/users";
//     readonly products: "/products";
//   };
//   readonly supportedLanguages: readonly ["en", "fr", "de"];
// }

У цьому прикладі об'єкт config, його вкладений об'єкт endpoints та масив supportedLanguages позначені як readonly. Це гарантує, що жодна частина конфігурації не може бути випадково змінена під час виконання.

Приклад 5: Const-ствердження з типами, що повертаються функцією

Ви можете використовувати const-ствердження, щоб гарантувати, що функція повертає незмінне значення. Це особливо корисно при створенні допоміжних функцій, які не повинні змінювати свої вхідні дані або створювати змінний вивід.


function createImmutableArray(items: T[]): readonly T[] {
  return [...items] as const;
}

const numbers = [1, 2, 3];
const immutableNumbers = createImmutableArray(numbers);

// Тип immutableNumbers: readonly [1, 2, 3]

// immutableNumbers[0] = 4; // Помилка: Індексна сигнатура в типі 'readonly [1, 2, 3]' дозволяє лише читання.

Сценарії та випадки використання

Управління конфігурацією

Const-ствердження ідеально підходять для управління конфігурацією застосунку. Оголошуючи ваші об'єкти конфігурації з as const, ви можете гарантувати, що конфігурація залишається незмінною протягом усього життєвого циклу застосунку. Це запобігає випадковим змінам, які можуть призвести до непередбачуваної поведінки.


const appConfig = {
  appName: "My Application",
  version: "1.0.0",
  apiEndpoint: "https://api.example.com",
} as const;

Визначення констант

Const-ствердження також корисні для визначення констант з конкретними літеральними типами. Це може покращити безпеку типів та чіткість коду.


const HTTP_STATUS_OK = 200 as const; // Тип: 200
const HTTP_STATUS_NOT_FOUND = 404 as const; // Тип: 404

Робота з Redux або іншими бібліотеками керування станом

У бібліотеках керування станом, таких як Redux, імутабельність є основним принципом. Const-ствердження можуть допомогти забезпечити імутабельність у ваших редьюсерах та творцях дій, запобігаючи випадковим мутаціям стану.


// Приклад редьюсера Redux

interface State {
  readonly count: number;
}

const initialState: State = { count: 0 } as const;

function reducer(state: State = initialState, action: { type: string }): State {
  switch (action.type) {
    default:
      return state;
  }
}

Інтернаціоналізація (i18n)

При роботі з інтернаціоналізацією ви часто маєте набір підтримуваних мов та відповідних їм кодів локалей. Const-ствердження можуть гарантувати, що цей набір залишатиметься незмінним, запобігаючи випадковим додаванням або змінам, які можуть зламати вашу реалізацію i18n. Наприклад, уявіть, що ви підтримуєте англійську (en), французьку (fr), німецьку (de), іспанську (es) та японську (ja):


const supportedLanguages = ["en", "fr", "de", "es", "ja"] as const;

type SupportedLanguage = typeof supportedLanguages[number]; // Тип: "en" | "fr" | "de" | "es" | "ja"

function greet(language: SupportedLanguage) {
  switch (language) {
    case "en":
      return "Hello!";
    case "fr":
      return "Bonjour!";
    case "de":
      return "Guten Tag!";
    case "es":
      return "¡Hola!";
    case "ja":
      return "こんにちは!";
    default:
      return "Greeting not available for this language.";
  }
}

Обмеження та міркування

Альтернативи const-ствердженням

Хоча const-ствердження є потужним інструментом для забезпечення імутабельності, існують й інші підходи, які ви можете розглянути:

Найкращі практики

Висновок

Const-ствердження в TypeScript є цінним інструментом для забезпечення імутабельності та покращення безпеки типів у вашому коді. Використовуючи as const, ви можете вказати компілятору вивести найвужчий можливий тип для значення та позначити всі властивості як readonly. Це допомагає запобігти випадковим змінам, покращити передбачуваність коду та розблокувати більш точну перевірку типів. Хоча const-ствердження мають деякі обмеження, вони є потужним доповненням до мови TypeScript і можуть значно підвищити надійність ваших застосунків.

Стратегічно впроваджуючи const-ствердження у свої проєкти на TypeScript, ви зможете писати більш надійний, підтримуваний та передбачуваний код. Скористайтеся потужністю виведення незмінних типів та вдосконалюйте свої практики розробки програмного забезпечення.