azovl
@azovl

Как правильно определять тип объекта в Typescript (React)?

Определяю тип как правило для получаемых или своих данных используя enums, type's, interfaces.
Также можно получить тип с помощью выражения:
instance.constructor.name

Но как быть если это не работает:
<button onClick={e => switchTheme(e)} … 

// Выдаст ошибку о том что имя не найдено
const switchTheme = (e: SyntheticBaseEvent) => {


SyntheticBaseEvent изменяю на MouseEvent но в строчке ниже пишет "TS2339: Property 'classList' does not exist on type 'EventTarget'.":
e.target.classList.remove(clickedClass);

Или к примеру:
interface ClickableProps {
    children: JSX.Element[] | JSX.Element;
}


Как понять что children относиться к типу JSX.Element..?
  • Вопрос задан
  • 543 просмотра
Решения вопроса 1
search
@search
мама говорит что я особенный
Тайпскрипт правильно ругается потому что таргет события не обязательно должен быть дом элементом. События могут так же порождаться, например XHR запросами.

Я бы на вашем месте сделал так называемую type guard функцию, в которой убеждался бы что таргет действительно элемент дом. Все элементы дом наследуются от объекта HTMLElement. Это можно использовать для проверки:

const isHtmlElement = (v: any): v is HTMLElement => v instanceof HTMLElement;


далее мы можем использовать эту функцию для проверки нашего таргета:

const eventHandler = (e: Event) => {
  if (!isHtmlElement(e.target)) {
    return;
  }
  // Вот здесь мы можем смело работать с таргетом как с ДОМ Элементом
  e.target.classList.toggle('active');
}


УПД

Еще информация к размышлению.

Финальный код, сгенерированный тайпскриптом, не содержит информации о типах. В рантайме нельзя узнать тип интерфейса, выполнив, например `peremennaya instanceof VashInterfeis`. Но всегда можно создать type guard функию, которая будет определять что объект именно нужного типа по каким-то косвенным признакам (например по наличию определённых полей в объекте). Так как код guard функции невозможно провертить статическим анализватором, тайпскрипт не может гарантировать того что ваша guard фунция верна и не пропускает всё подряд. Поэтому, хорошим тоном является писать такой код, который не нуждается в подобных проверках. Это возможно. Код при таком подходе становится стройнее и легче для осмысления.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
w3bsmes
@w3bsmes
Куратор тега «Глупые вопросы»
Действительно, почему?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы