Задать вопрос
@devdev10111

Как правильно объединить два типа HTMLElement?

Привет! Есть компонент, корнем которого может быть либо тег a, либо button. Это будет решаться в зависимости от наличия пропа href

const TappableComponent = (props: TappableComponentProps) => {
     const Component = props?.href ? 'a' : 'button';
     return <Component>...</Component>
}


Соответственно, нужно чтобы в пропсах можно было указать все аттрибуты от button и от a. Сделал так:
interface TappableComponentProps extends
  Partial<AnchorHTMLAttributes<HTMLAnchorElement>>,
  Partial<ButtonHTMLAttributes<HTMLButtonElement>> {
  size?: 's' | 'm' | 'l';
}

но ts ругается на большое количество не идентичных типов в AnchorHTMLAttributes и ButtonHTMLAttributes.

вручную вытягивать через
Pick<ButtonHTMLAttributes<HTMLButtonElement>, 'href' | 'target' | etc>

кажется неверным методом, может есть решение получше?
  • Вопрос задан
  • 120 просмотров
Подписаться 1 Простой 3 комментария
Помогут разобраться в теме Все курсы
  • Нетология
    Frontend-разработка на React
    10 недель
    Далее
  • ProductStar
    Разработка на React
    6 недель
    Далее
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
Решения вопроса 1
Aetae
@Aetae Куратор тега TypeScript
Тлен
Ответ Александр хорошо работает если есть дискриминатор (в приведённом примере поле type).

Если же такого уникального поля нет, то конкретно для React можно сделать на перегрузках, условно:
type ExtraProps = {
  size?: 's' | 'm' | 'l';
}

type AnchorProps = ExtraProps & {href: string};
type ButtonProps = ExtraProps & {type: string};

function TappableComponent(props: AnchorProps ): ReactNode; 
function TappableComponent(props: ButtonProps ): ReactNode;
function TappableComponent(props: AnchorProps | ButtonProps ) {
     const Component = 'href' in props ? 'a' : 'button';
     return <Component>...</Component>
}

Там множество подводных камней, но иногда удобно.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы
от 250 000 до 300 000 ₽
ITK academy Нижний Новгород
от 50 000 до 90 000 ₽
ITK academy Екатеринбург
от 50 000 до 90 000 ₽