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

Что такое TypeGuard в TypeScript

TypeGuard — это механизм в TypeScript, который помогает сузить тип переменной в пределах блока кода. Он позволяет TypeScript точно определить тип переменной на основе условий, что делает код более безопасным и позволяет компилятору лучше проверять типы.

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

Принцип работы TypeGuard

TypeScript предоставляет несколько способов реализации TypeGuard, включая:

  1. Пользовательские функции TypeGuard.
  2. Операторы проверки типа, такие как typeof и instanceof.
  3. Кастомные проверки типов с использованием is.

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

  1. Пример с typeof:

    Оператор typeof позволяет проверять примитивные типы, такие как string, number, boolean и другие. В случае с TypeGuard это позволяет сузить тип переменной в блоке кода.

    function printLength(value: string | number) {
      if (typeof value === "string") {
        console.log(value.length);  // Работает, так как value точно строка
      } else {
        console.log(value.toFixed(2)); // Работает, так как value точно число
      }
    }
    
    printLength("Hello");  // Выведет: 5
    printLength(42);       // Выведет: 42.00
    

    В этом примере, оператор typeof позволяет TypeScript понять, что в блоке if переменная value является строкой, а в блоке else — числом.

  2. Пример с instanceof:

    Оператор instanceof используется для проверки типов объектов, например, классов. Это позволяет точно определить тип объекта, если он является экземпляром какого-то класса.

    class Dog {
      bark() {
        console.log("Woof!");
      }
    }
    
    class Cat {
      meow() {
        console.log("Meow!");
      }
    }
    
    function speak(animal: Dog | Cat) {
      if (animal instanceof Dog) {
        animal.bark();  // Доступ к методу bark, так как animal — это Dog
      } else {
        animal.meow();  // Доступ к методу meow, так как animal — это Cat
      }
    }
    
    const dog = new Dog();
    const cat = new Cat();
    
    speak(dog);  // Выведет: Woof!
    speak(cat);  // Выведет: Meow!
    
  3. Пользовательские TypeGuard функции

    Вы можете создавать свои собственные функции для проверки типов и использования TypeGuard с помощью ключевого слова is.

    type Dog = { bark: () => void };
    type Cat = { meow: () => void };
    
    function isDog(animal: Dog | Cat): animal is Dog {
      return (animal as Dog).bark !== undefined;
    }
    
    function speak(animal: Dog | Cat) {
      if (isDog(animal)) {
        animal.bark();  // animal теперь точно тип `Dog`
      } else {
        animal.meow();  // animal теперь точно тип `Cat`
      }
    }
    
    const dog: Dog = { bark: () => console.log("Woof!") };
    const cat: Cat = { meow: () => console.log("Meow!") };
    
    speak(dog);  // Выведет: Woof!
    speak(cat);  // Выведет: Meow!
    

Почему стоит использовать TypeGuard?

  • Типовая безопасность: TypeGuard помогает избежать ошибок, связанных с неправильным использованием переменных, так как TypeScript точно понимает, какой тип переменной используется в каждом блоке кода.

  • Улучшение читаемости кода: Использование TypeGuard делает код более понятным и предсказуемым, так как явно указывает, какие типы данных обрабатываются в каждом блоке.

  • Лучшее понимание кода для IDE: TypeScript и IDE (например, Visual Studio Code) могут использовать TypeGuard для улучшения подсказок, автодополнения и рефакторинга, что ускоряет разработку и улучшает работу с кодом.