DevGang
Авторизоваться

Как перестроить проект Front End Mentor с помощью TypeScript

В этой статье мы хотим показать вам, как использовать TypeScript, чтобы переписать код для проекта Front End Mentor. Front End Mentor — отличная платформа для создания проектов в качестве разработчика программного обеспечения и не застревать в учебном аду. Для тех, кто не знаком с TypeScript, позвольте дать вам базовое представление о том, что это такое.

Что такое TypeScript?

TypeScript — это надмножество JavaScript. Это означает, что любой действительный код JavaScript также является допустимым кодом TypeScript, что позволяет легко постепенно внедрять TypeScript в любой существующий проект JavaScript. Одной из наиболее важных функций TypeScript, привнесенных в JavaScript, является проверка типов. JavaScript не строг с проверкой типов, вы можете объявить переменную числом, а затем изменить ее на строку где-нибудь еще без каких-либо ошибок (конечно, пока вы не запустите код). Вот пример:

let num = 10;

num = "Hello";

console.log(num); // This is perfectly fine with JavaScript

Если вы использовали такие языки, как Java, C#, C++ и т.д., вы знаете, что в эти языки встроена проверка типов. TypeScript ввел проверку типов в JavaScript, чтобы уменьшить количество ошибок в нашем коде (как показано выше) и помочь нам писать код, готовый к использованию. С помощью TypeScript вы объявляете типы своих переменных, чтобы TypeScript мог предупредить вас, когда вы пытаетесь сделать что-то не так. Есть и другие функции TypeScript, но проверка типов — самая важная функция TypeScript, которая упрощает написание кода на JavaScript. Чтобы начать использовать TypeScript, вам необходимо установить его глобально в вашей системе с помощью npm.

npm install -g typescript

Затем создайте файл .ts в папке вашего проекта, например index.ts, и поместите этот простой фрагмент:

let num: number = 10

Чтобы запустить этот код с помощью компилятора TypeScript, откройте терминал и выполните эту команду:

tsc index.ts

Это преобразует код из TypeScript в JavaScript!. Теперь, когда у вас есть базовое представление о том, что такое TypeScript и как его использовать, позвольте показать вам, как использовать его, чтобы переписать свой проект FEM.

Проект

Это проект подписки на рассылку новостей, который сделан от Front End Mentor. Преобразование кода этого проекта — непростое занятие, но оно может вывести вас из зоны комфорта и помочь узнать гораздо больше о TypeScript. Вот репозиторий Github и предварительный просмотр приложения, если вы хотите их проверить. Вот HTML-код приложения:

 <main>
      <section id="newsletter" class="newsletter">
        <picture class="newsletter__image">
          <source
            srcset="assets/images/illustration-sign-up-desktop.svg"
            media="(min-width: 81.25em)"
          />

          <img src="assets/images/illustration-sign-up-mobile.svg" alt="" />
        </picture>

        <div class="newsletter__content">
          <h2>Stay updated!</h2>

          <p>Join 60,000+ product managers receiving monthly updates on:</p>

          <ul class="newsletter__features">
            <li class="feature__item">
              Product discovery and building what matters
            </li>

            <li class="feature__item">
              Measuring to ensure updates are a success
            </li>

            <li class="feature__item">And much more!</li>
          </ul>

          <form method="POST" class="newsletter__form">
            <label for="email">Email address</label>
            <input
              type="email"
              name="email"
              id="email"
              class="newsletter__input"
              placeholder="email@company.com"
            />

            <span class="form-error"></span>

            <button type="submit" class="subscribe__btn">
              Subscribe to monthly newsletter
            </button>
          </form>
        </div>
      </section>

      <section id="subscription-message" class="subscription__success d-none">
        <div class="subscription__message">
          <img
            src="./assets/images/icon-success.svg"
            class="subscription__icon"
            alt=""
          />

          <h3 class="subscription__heading">Thanks for subscribing!</h3>

          <p class="subscription__content">
            A confirmation email has been sent to
            <span class="subscription__email"></span>. Please open it and click
            the button inside to confirm your subscription.
          </p>
        </div>

        <button id="dismiss" class="subscribe__btn">Dismiss message</button>
      </section>
    </main>

Это код JavaScript:

const newsletter = document.querySelector("#newsletter");
const newsletterForm = document.querySelector(".newsletter__form");
const subscriptionMessage = document.querySelector("#subscription-message");
const formInput = document.querySelector(".newsletter__input");
const formError = document.querySelector(".form-error");
const dismissBtn = document.querySelector("#dismiss");
const emailText = document.querySelector(".subscription__email");
const emailRegex = /^[a-zA-Z]+@[a-zA-Z]+\.[a-zA-Z]{2,4}$/;

newsletterForm.addEventListener("submit", (e) => {
  e.preventDefault();

  let status = true;

  if (formInput.value == "") {
    status = false;
    formInput.classList.add("newsletter__input--error");
    formError.innerHTML = "Email is required";
  }

  if (formInput.value != "" && formInput.value.match(emailRegex) === null) {
    status = false;

    formInput.classList.add("newsletter__input--error");
    formError.innerHTML = "Invalid email address";
  }

  if (status) {
    newsletter.classList.add("d-none");
    subscriptionMessage.classList.remove("d-none");
    emailText.innerHTML = formInput.value;
  }
});

formInput.addEventListener("input", () => {
  if (formInput.classList.contains("newsletter__input--error")) {
    formInput.classList.remove("newsletter__input--error");
    formError.innerHTML = "";
  }
});

dismissBtn.addEventListener("click", () => {
  newsletter.classList.remove("d-none");
  subscriptionMessage.classList.add("d-none");
});

Не будем объяснять всю кодовую базу, а только ту, которая связана с реализацией TypeScript. Первое, что нужно было сделать, это определить типы для некоторых переменных, которые мы объявили выше, потому что когда вы выбираете элементы в DOM, они имеют тип по умолчанию Element, это общий тип, который не имеет конкретных свойств и методов для элементов HTML, таких как <form>, <button> и т.д. Переменная newsletterForm, например, является элементом формы. Если тип не изменен, мы не сможем получить доступ к определенным свойствам и методам, доступным для элементов формы, например, e.preventDefault(), потому что TypeScript недостаточно умен, чтобы знать, что мы выбираем элемент формы. Один из способов указать нужные типы в TypeScript — использовать технику под названием Type Assertion.

Что такое Type Assertion?

Type Assertion сообщает TypeScript, что вы уверены в типе элемента или переменной, когда TypeScript не уверен. Например, TypeScript не знает, что такое newsletterForm, поэтому мы можем использовать утверждение типа, чтобы сообщить ему, что эта переменная является элементом формы HTML.

const newsletterForm = document.querySelector(".newsletter__form") as HTMLFormElement;

Следующее, что мы делаем в коде, — это присоединяем прослушиватель событий к элементу формы.

newsletterForm.addEventListener("submit", (e) => {});

Мы сказали TypeScript, что newsletterForm — это элемент формы, но что, если элемент, который мы назначили переменной newsletterForm, не существует? Или переменная не определена? Мы столкнемся с этой проблемой.

Uncaught TypeError: невозможно прочитать свойства null

Вы, должно быть, уже видели эту ошибку в своей консоли, так как же решить эту проблему? Используя так называемое необязательное связывание. Необязательный оператор цепочки используется для безопасного доступа к свойствам или методам объекта без ненужных ошибок. Если объект не определен, код оказывается замкнутым, и любой код, написанный после него, никогда не будет выполнен. Например, вот как будет использоваться необязательный оператор цепочки с переменной newsForm.

newsletterForm?.addEventListener("submit", (e) => {});

Теперь мы уверены, что даже если newsletterForm возвращает значение null, код прослушивателя событий никогда не выполнится, что делает наш код более безопасным. Давайте теперь добавим код прослушивателя событий:

Существует проблема с оператором if, TypeScript показывает красную пунктирную линию на переменной formInput, почему? Поскольку он не уверен, что такое formInput, вы можете использовать дополнительную цепочку, чтобы решить эту проблему. Следующая проблема, с которой мы столкнулись, — это попытка получить доступ к свойству value, поскольку TypeScript интерпретирует formInput как тип Element, а тип Element не имеет свойства value, поэтому нам также нужно сообщить TypeScript, что formInput — это HTMLInputElement.

const formInput = document.querySelector(".newsletter__input") as HTMLInputElement;

newsletterForm?.addEventListener("submit", (e) => {
  e.preventDefault();

  let status = true;

  if (formInput?.value == "") {
    ...
  }
});

Нам также необходимо исправить переменную formError, поскольку TypeScript жалуется, что не знает, что такое formError. В этом случае нам сначала нужно проверить, не возвращает ли formError значение null, прежде чем мы попытаемся изменить значение InnerHTML, потому что вы не можете выполнять операции присваивания с помощью необязательного оператора цепочки, поскольку есть вероятность, что переменная не будет существовать.

newsletterForm?.addEventListener("submit", (e) => {
  e.preventDefault();

  let status = true;

  if (formInput?.value == "") {
    status = false;

    formInput?.classList.add("newsletter__input--error");

    if (formError) {
      formError.innerHTML = "Email is required";
    }
  }

  if (formInput?.value != "" && formInput?.value.match(emailRegex) === null) {
    status = false;

    if (formError) {
      formInput?.classList.add("newsletter__input--error");
      formError.innerHTML = "Invalid email address";
    }
  }
});

Затем мы переходим к другому прослушивателю событий, который слушает, когда пользователь вводит текст в поле ввода.

formInput.addEventListener("input", () => {
  if (formInput.classList.contains("newsletter__input--error")) {
    formInput.classList.remove("newsletter__input--error");
    formError.innerHTML = "";
  }
});

Это та же проблема, которую мы уже решали ранее, используя необязательный оператор цепочки и проверяя, существует ли formError перед установкой значения innerHTML.

formInput?.addEventListener("input", () => {
  if (formInput.classList.contains("newsletter__input--error")) {
    formInput.classList.remove("newsletter__input--error");

    if (formError) {
      formError.innerHTML = "";
    }
  }
});

Мы также сделаем то же самое для кнопки закрытия, к которой мы добавили прослушиватель событий.

dismissBtn?.addEventListener("click", () => {
  newsletter?.classList.remove("d-none");
  subscriptionMessage?.classList.add("d-none");
});

Заключение

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

Источник:

#JavaScript #TypeScript
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу