Весной стартует сезон найма, успей отхватить свой оффер!

Utility Type Readonly в TypeScript

Readonly — это utility тип в TypeScript, который делает все свойства типа только для чтения (read-only). После того, как свойство становится readonly, оно не может быть изменено при прямом присвоении в коде, что помогает избежать непреднамеренных мутаций объекта.

Синтаксис

Readonly<T> 
  • T — исходный тип, все свойства которого вы хотите сделать неизменяемыми.

Тип Readonly чаще всего используется, чтобы защитить объекты от нежелательных изменений, сохраняя при этом доступ к чтению их свойств.

Когда использовать Readonly?

  • Если объект не должен изменяться после создания.
  • Для работы с константными объектами.
  • При передаче данных в функцию, чтобы избежать случайных изменений.

Пример использования Readonly

  • Создание объекта с неизменяемыми свойствами:
    interface User {
      id: number;
      name: string;
    }
    
    type ReadonlyUser = Readonly<User>;
    
    const user: ReadonlyUser = {
      id: 1,
      name: "Alice",
    };
    
    user.name = "Bob"; 
    // Ошибка: Cannot assign to 'name' because it is a read-only property` 
  • Здесь ReadonlyUser превращает все свойства ( id и name) в readonly.
  • Попытка изменить какое-либо свойство приводит к ошибке на этапе компиляции.

Пример для неизменяемых конфигураций:

Иногда бывает нужно зафиксировать настройки, чтобы их нельзя было изменить после инициализации:

interface Config {
    readonly port: number;  // Уже задано явно
    dbName: string;
}

// С помощью Readonly делаем все поля только для чтения
type FullReadonlyConfig = Readonly<Config>;

const config: FullReadonlyConfig = {
    port: 8080,
    dbName: "mainDB",
};

config.dbName = "testDB"; 
// Ошибка: 'dbName' is read-only` 
  • У поля port стоит readonly, но также и dbName становится readonly, когда мы оборачиваем весь интерфейс в Readonly<Config>.

Использование в функциях

  • Гарантия неизменности аргумента
    Можно объявлять параметры функции как Readonly<T>, чтобы не допустить случайных изменений передаваемого объекта:
function printUser(user: Readonly<User>) {
    // user.id = 42;   // Ошибка
    console.log(user.id, user.name);
}
  • Это защищает от мутаций объекта внутри функции.

Итог

  • Readonly — удобный способ защитить свойства объекта от изменений.
  • Применяется, когда вы хотите явно указать, что объект должен оставаться неизменным на протяжении использования.
  • При попытке присвоить что-либо свойству readonly, TypeScript выдаст ошибку на этапе компиляции, помогая избежать непреднамеренных мутаций.